About a year ago I started playing with Nix and it has become as essential as Docker and Emacs for my local development environments. I switched from a world of direnv and virtualenv based environments to one with direnv and nix. The Nix part seems complicated but it's really not. I really just uses a sliver of what Nix does and I'm fine with it. See what my friend Marty wrote for a good discussion on what Nix is, how to install it and several reasons why it's awesome.

As I said above, my setup is pretty basic but it does everything I hoped it could do.

In the Direnv file I have usual environment variables, maybe a couple PATH settings for scripts and then at the end:

use nix

and... that is it for direnv.

Then I make a file called shell.nix that creates the python environment

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {

  buildInputs = [
    pkgs.python38
    pkgs.poetry
    pkgs.black

  ];

}

That is a simple one. Here is some that is Python and a few more things:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {

  buildInputs = [
    pkgs.python3
    pkgs.poetry
    pkgs.python3Packages.pip
    pkgs.pgcli
    pkgs.postgresql
    pkgs.libxml2
    pkgs.libxslt
  ];

}

This is a lot like previous one, but with some Postgresql helpers and the XML libraries are there because some Python libraries I use needed them.

Then do the direnv allow ... and you have your environment setup. Nix handles the install and maintance of what I specified in my shell file. Which you can see when you look at the Python executable:

➜ which python
/nix/store/df2vs5yxfwj2flslf6ng0a0w8swdwgp7-python3-3.9.9/bin/python

After that I go into the folder and/or open my project with Emacs.. and my environment is set up. I can use plain Poetry commands and it will be a "normal" Python project... because it is a normal Python project! With just the executables setup for Nix.

My examples above were all for Python but it's really for any type of dev platform. Here is a React project that I have setup:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {

  buildInputs = [
     pkgs.yarn
     pkgs.nodejs-14_x

  ];

}

No messy rvm or anything -- just set your version and let Nix do all the work