Nix shells

From wikinotes

Nix shell allows you to describe/load a shell environment in shell.nix.
If it is not present, you can load the build environment from default.nix.


You can also dynamically resolve shells from a list of packages or a submitted nix expression.

Documentation

creating a shell docs https://nixos.org/nixpkgs/manual/#creating-a-shell
nix development environments https://nixos.wiki/wiki/Development_environment_with_nix-shell

Examples

shell.nix example (shell environment)


# package/shell.nix

{ pkgs ? import <nixpkgs> {} }:

with pkgs;

let
  inherit hello;

in
mkShell {
  buildInputs = [ hello ];  # nix requirements
  shellHook = ''            # cli commands within shell
    echo "hi"
    echo "there"
  '';
  HELLO_ENV="hello";        # environment variables
}

Now just nix-shell to enter environment

nix-shell        # interpret shell.nix
hello            #> 'hello, world'
echo $HELLO_ENV  #> 'hello'


default.nix example (build environment)

# package/default.nix

{ pkgs ? import <nixpkgs> {} }:

with pkgs; # use pkgs namespace

let
  inherit hello;

in
  pkgs.stdenv.mkDerivation {
    name = "foo-1.0.0";       # package name
    buildInputs = [ hello ];  # nix requirements
    HELLO_ENV="hello";        # environment variables
}
nix-shell        # interactive shell for package
echo $HELLO_ENV  # environment variable set


If you're working within a package environment, you can do other tricks like loading
default.nix, leaving hooks to load a local.nix etc.
See nix packages for details.

direnv integration

direnv allows you to automatically enable nix-shell as you cd into a directory
and it does so while retaining your current shell, environment variables etc.

direnv also allows you to add instructions in parent directories.
This is useful if for example you'd like to inject neovim language extensions for all projects.

If you're installing direnv with the intention of using it for nix,
install it using nix instead of using your distro's package repository (I've had problems, at least on arch).

nix-env -i direnv

Community

NOTE:

recommended if managing python requirements via nix+virtualenv

An improved use_nix integration between direnv and nix. https://github.com/nix-community/nix-direnv
It executes faster, and nix-shell environments persist.

# NOTE: instructions vary based on nixos/home-manager/nix-env
nix-env -f '<nixpkgs>' -iA nix-direnv
# /etc/nix/nix.conf

keep-derivations = true
keep-outputs = true

builtin

direnv has nix integrations that let you automatically enter nix-shell as you cd into the directory.

Builtin direnv nix integration.

# package/.envrc
use_nix

Editor Overlays

Your desired dev environment may have requirements of it's own
For example my development vim config requires on marktag, python-neovim, solargraph, etc.
My preference is to load an environment based on the projects with additional packages installed.

This can be achieved using overlays. See nix configuration.