'shell.nix' but with flakes

‘nix-shell’ has two purposes: opening a shell to use packages (e.g. nix-shell -p hello, producing a shell where hello is available), and opening a shell to build a project interactively (e.g. nix-shell '<nixpkgs>' -A hello, producing a shell where e.g. buildPhase is available to build hello).

This post is about using nix-shell to use packages, not build them. I often use shell.nix to store exactly the environment needed to work with a certain project. For example, when I work on akka (which is not packaged for Nix and I’m not sure that would make sense), I use the following shell.nix:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  name = "akka";
  buildInputs = [
    (pkgs.sbt.override {
      jre = pkgs.jdk11;
    })
    pkgs.graphviz
    pkgs.multimarkdown
    pkgs.diffoscope
  ];

  JAVA_8_HOME = "${pkgs.jdk8}/lib/openjdk";
  JAVA_11_HOME = "${pkgs.jdk11}/lib/openjdk";
}

This works great, however, with the new nix commands and Flakes being the New Hotness I wanted to try that out. If I understand correctly, the Flakes equivalent of “nix-shell for using packages” is nix shell, where the equivalent for “nix-shell for building packages interactively” is nix develop - so it sounds like I want nix shell.

How do I store my desired shell in a flake? nix shell --help only seems to show examples of using nix shell specifying the packages on the command line.

(I know I could populate devShell and use nix develop, but that seems like going against the grain: for example, nix shell will use my favorite shell while nix develop, for reasonable reasons, uses bash. I could also just save the nix shell invocation in some script, but that’d get uncomfortable for environments with more tweaks/overrides/etc)

6 Likes

Use nix develop --command zsh and devShell for the time being. Upstream hasn’t entirely decided yet which command should take on this functionality: "Lighter" and "cleaner" shell for `nix develop` and `nix shell` · Issue #4609 · NixOS/nix · GitHub

An alternative is maybe nix run with a shell defined in packages (or explicitly calling the #devShells.<system>.default), but I don’t think that will behave any different than nix develop regarding shell use. And of course direnv is always nice.

3 Likes

Thanks for that link, that’s helpful to understand the status quo! I like the idea from the bottom of that thread to somehow push the logic for creating a shell-with-particular-commands-available to the ‘nix side’ and avoiding having too much ‘magic behavior’ in the nix shell command implementation.

Tried things about a bit at https://codeberg.org/raboof/nix-flake-shell/src/branch/main/flake.nix - needs more thought though, and I need to learn more about how nix-shell, nix shell and nix develop actually work :wink:

1 Like