A faster, persistent implementation of direnv
's use_nix
and use_flake
, to
replace the built-in one.
Prominent features:
nix-shell
environmentgcroots
(Life is too short to lose your
project's build cache if you are on a flight with no internet connection)lorri
instead?Compared to lorri, nix-direnv is simpler (and requires no external daemon) and supports flakes. Additionally, lorri can sometimes re-evaluate the entirety of nixpkgs on every change (leading to perpetual high CPU load).
Heads up: nix-direnv requires a modern Bash. MacOS ships with bash 3.2 from 2007. As a work-around we suggest that macOS users install
direnv
via Nix or Homebrew. There are different ways to install nix-direnv, pick your favourite:
Either add shell.nix
or a default.nix
to the project directory:
# save this as shell.nix
{ pkgs ? import <nixpkgs> {}}:
pkgs.mkShell {
packages = [ pkgs.hello ];
}
Then add the line use nix
to your envrc:
$ echo "use nix" >> .envrc
$ direnv allow
If you haven't used direnv before, make sure to hook it into your shell first.
You may use a different file name than shell.nix
or default.nix
by passing
the file name in .envrc
, e.g.:
$ echo "use nix foo.nix" >> .envrc
nix-direnv also comes with an alternative use_flake
implementation. The code
is tested and does work but the upstream flake api is not finalized, so we
cannot guarantee stability after a nix upgrade.
Like use_nix
, our use_flake
will prevent garbage collection of downloaded
packages, including flake inputs.
This repository ships with a
flake template.
which provides a basic flake with devShell integration and a basic .envrc
.
To make use of this template, you may issue the following command:
$ nix flake new -t github:nix-community/nix-direnv <desired output path>
$ echo "use flake" >> .envrc && direnv allow
The use flake
line also takes an additional arbitrary flake parameter, so you
can point at external flakes as follows:
use flake ~/myflakes#project
Under the covers, use_flake
calls nix print-dev-env
. The first argument to
the use_flake
function is the flake expression to use, and all other arguments
are proxied along to the call to print-dev-env
. You may make use of this fact
for some more arcane invocations.
For instance, if you have a flake that needs to be called impurely under some
conditions, you may wish to pass --impure
to the print-dev-env
invocation so
that the environment of the calling shell is passed in.
You can do that as follows:
$ echo "use flake . --impure" > .envrc
$ direnv allow
Like use flake
, use nix
now uses nix print-dev-env
. Due to historical
reasons, the argument parsing emulates nix shell
.
This leads to some limitations in what we can reasonably parse.
Currently, all single-word arguments and some well-known double arguments will be interpreted or passed along.
To avoid delays and time consuming rebuilds at unexpected times, you can use nix-direnv in the "manual reload" mode. nix-direnv will then tell you when the nix environment is no longer up to date. You can then decide yourself when you want to reload the nix environment.
To activate manual mode, use nix_direnv_manual_reload
in your .envrc
like
this:
nix_direnv_manual_reload
use nix # or use flake
To reload your nix environment, use the nix-direnv-reload
command:
$ nix-direnv-reload
-p
: Starts a list of packages to install; consumes all remaining arguments--include
/ -I
: Add the following path to the list of lookup locations for
<...>
file names--attr
/ -A
: Specify the output attribute to utilize--command
, --run
, --exclude
, --pure
, -i
, and --keep
are explicitly
ignored.
All single word arguments (-j4
, --impure
etc) are passed to the underlying
nix invocation.
As a convenience, nix-direnv
adds common files to direnv's watched file list
automatically.
The list of additionally tracked files is as follows:
for use nix
:
~/.direnvrc
~/.config/direnv/direnvrc
.envrc
,use nix
default.nix
if it existsshell.nix
if it existsfor use flake
:
~/.direnvrc
~/.config/direnv/direnvrc
.envrc
flake.nix
flake.lock
devshell.toml
if it existsUsers are free to use direnv's builtin watch_file
function to track additional
files. watch_file
must be invoked before either use flake
or use nix
to
take effect.
nix-direnv sets the following environment variables for user consumption. All other environment variables are either a product of the underlying nix invocation or are purely incidental and should not be relied upon.
NIX_DIRENV_DID_FALLBACK
: Set when the current revision of your nix shell or
flake's devShell are invalid and nix-direnv has loaded the last known working
shell.