Portable dev environments

In my journey to uncruft my system, I started looking at even uncrufting my user's footprint as well. I found myself bringing in a ton of things for misc dev work. One project I may use Nim, another Python, another I need Zola for this blog, and it started adding up. I knew there had to be a better way. In comes nix-direnv. If you have done development, you may already be familiar with direnv which is great for keeping your system clean in general. I won't repeat everything when there are good links to things, but direnv is built to keep your env vars that are project specific out of your local system, and nix-direnv extends that now to packages! Instead of rambling, I'll show you a simple demo that I actually use on this blog.

You'll need two files for each project.


use nix


    { pkgs ? import <nixpkgs> {}}:

    pkgs.mkShell {
      nativeBuildInputs = with pkgs; [

You'll obviously want to install direnv and nix-direnv in whatever way you would normally. I simply included them in my home-manager file. Deperinding on how you have your shell installed, you may need to add a hook for your shell to automatically load the environment when you change into the directory. Since I don't allow nix to manage my ZSH configuration, I simply added it to my .zshrc, though it may be more readable to most people with the shown example.

# .zshrc
eval "$(direnv hook zsh)"

If you have a different shell, follow the docs for your specific shell. That should be it in terms of global setup. .envrc files won't be loaded by default for security, so you can run direnv allow . in the directory once and it will be allowed to load from that point on when you cd into the directory, and unload when you leave.

After thoughts

Not only does this allow you to keep your system cleaner by keeping env vars and packages out of the system and user's packages, it allows you to keep that portable for anyone that has a nix system with direnv and nix-direnv so there's no need to guess what packages are missing for nix as they can auto populate. If you want to adventure further into it, you can even do things like fetching remote envs, version locking to keep all users on the same dev environment, and much more, but that's outside of the scope of this. This is just meant to give you something to start with, or it may already do everything you could possibly need. Hope that helps someone understand what it does so you don't have to dig up everything like I had to.