direnv
(along with nix-direnv) allows one to persist
1
nix development shell environments and share them seamlessly with text editors and IDEs. It obviates having to run nix develop
manually every time you open a new terminal. The moment you cd
into your project directory, the devshell is automatically activated, thanks to direnv
.
It is recommended to use starship along with nix-direnv, because it gives a visual indication of the current environment. For example, if you are in a Nix Shell, your terminal prompt automatically changes to something like this:
srid on nixos haskell-template on master [!] via λ 9.2.6 via ❄️ impure (ghc-shell-for-haskell-template-0.1.0.0-0-env)
❯
Setup
If you use home-manager, both nix-direnv
and starship
can be installed using the following configuration:
# home.nix
programs.direnv = {
enable = true;
nix-direnv.enable = true;
};
programs.starship = {
enable = true;
};
If you have never used home-manager before, we recommend that you set it up by following the instrutions at https://github.com/juspay/nixos-unified-template (which is based on nixos-unified, thus works on macOS and Linux).
Text Editor configuration
VSCode
For VSCode, use Martin Kühl’s direnv extension.
Doom Emacs
Doom Emacs has the :tools
direnv
module to automatically load the devshell environment when you open the project directory.
Add a .envrc
To enable direnv on Flake-based projects, add the following to your .envrc
:
use flake
Now run direnv allow
to authorize the current .envrc
file. You can now cd
into the project directory in a terminal and the devshell will be automatically activated.
Reload automatically when some files change
Haskell - when .cabal
files change
Since both nixpkgs and haskell-flake use Nix expressions that read the .cabal
file to get dependency information, you will want the devshell be recreated every time a .cabal
file changes. This can be achieved using the watch_file
function. Modify your .envrc
to contain:
watch_file *.cabal
use flake
As a result of this whenever you change a .cabal
file, direnv will reload the environment. If you are using VSCode, you will see a notification that the environment has changed, prompting you to restart it (see example).