Direnv: use flake/nix according to availability

  1. direnv can automatically enable environments defined shell.nix or flake.nix. In the former case, you need to write use nix in the .direnv file, in the latter it’s use flake.

  2. github:edolstra/flake-compat allows you to write a shell.nix which uses the contents of flake.nix for use in nix environments which do not have flakes enabled

  3. Flakes are, at the time of writing, still disabled by default in nix.

Is it possible to arrange for direnv to use the flake, if flakes are enabled, and fall back on shell.nix if they are not?

Seems quite simple. In your .envrc:

if nix flake show &> /dev/null; then
  use flake
  use nix

When I try this without flakes enabled, I get this output:

$ direnv reload
direnv: loading ~/repos/experiments/direnv-maybe-flake/.envrc
direnv: using nix

And if I then enable flakes in my /etc/nix/nix.conf:

$ direnv reload
direnv: loading ~/repos/experiments/direnv-maybe-flake/.envrc
direnv: using flake

This works because .envrc files are just shell scripts. All the fancy functionality (like use flake) you know from direnv comes from its built-in stdlib.

1 Like

You can also pass nix options to use flake like this:

use flake --experimental-features 'nix-command flakes'

Unless I’m messing something up, it seems that the second, more concise, solution prevents direnv from updating the environment automatically when flake.nix changes, while the first, more verbose, solution doesn’t suffer from this problem.

It does for me. Not sure how to debug this, but you could double down by adding watch_file flake.nix maybe?