How I use Nix in my Elm projects
Tags: nix, elm, webdev
Published: 2023-12-19 11:18:34

---
title: How I use Nix in my Elm projects
published: true
description: I share how I use Nix in my Elm projects.
tags: nix, elm, webdev
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-12-19 11:15 +0000
---

[Nix](https://nixos.org/) is a tool that allows you to make reproducible development environments. I've started using it in all my Elm side projects and I've had a good experience with it thus far. To pique your curiosity I just wanted to share my simple setup that has been working quite well for me.

When I first started using Nix I used `nix-shell` with a `shell.nix` file but I've recently switched to [Nix flakes](https://nixos.wiki/wiki/Flakes) which uses `nix develop` with a `flake.nix` file.

## nix-shell

Here's an example `shell.nix` taken from my [elm-7guis](https://github.com/dwayne/elm-7guis) web application.

```nix
let
  pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/7f256d7da238cb627ef189d56ed590739f42f13b.tar.gz") {};
in
pkgs.mkShell {
  packages = [
    pkgs.caddy
    pkgs.elmPackages.elm
    pkgs.elmPackages.elm-format
    pkgs.elmPackages.elm-optimize-level-2
    pkgs.elmPackages.elm-review
    pkgs.elmPackages.elm-test
    pkgs.nodejs_18
    pkgs.shellcheck
  ];

  shellHook =
    ''
    export project="$PWD"
    export build="$project/.build"

    export PATH="$project/bin:$PATH"
    '';
}
```

When I run `nix-shell` at the root of the project it puts me in a Nix shell that contains, among other programs, [`caddy`](https://caddyserver.com/) and [`shellcheck`](https://www.shellcheck.net/). Notice that in the `shellHook` I add the project's shell scripts to the `PATH`. So once I'm in the Nix shell I can, among other things:

1. Serve the main application with Caddy using [`serve`](https://github.com/dwayne/elm-7guis/blob/f7bf120c2cb1bf0520bdf1921bd063af1aacc3b2/bin/serve).
2. Serve the prototype with Caddy using [`serve-prototype`](https://github.com/dwayne/elm-7guis/blob/f7bf120c2cb1bf0520bdf1921bd063af1aacc3b2/bin/serve-prototype).
3. Find any bugs in the shell scripts with ShellCheck using [`check`](https://github.com/dwayne/elm-7guis/blob/f7bf120c2cb1bf0520bdf1921bd063af1aacc3b2/bin/check).

In some projects I've wanted to use [HTTPie](https://httpie.io/) to test APIs and [jq](https://jqlang.github.io/jq/) to work with some JSON data. Nix has been really helpful in managing those dependencies that I can't easily get from [npm](https://www.npmjs.com/).

## nix develop

Here's an example `flake.nix` taken from my [elm-integer](https://github.com/dwayne/elm-integer/tree/d499f0937d2360d65f0e785e6cd36237fa935409) library.

```nix
{
  description = "A developer shell for working on elm-integer.";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=23.11";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils, ... }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = nixpkgs.legacyPackages.${system};
      in
      {
        devShells.default = pkgs.mkShell {
          name = "elm-integer";

          packages = with pkgs.elmPackages; [
            elm
            elm-doc-preview
            elm-format
            elm-optimize-level-2
            elm-test
            pkgs.caddy
            pkgs.nodejs_20
            pkgs.nodePackages.terser
            pkgs.shellcheck
          ];

          shellHook =
            ''
            export project="$PWD"
            export build="$project/.build"
            export PATH="$project/bin:$PATH"

            npm install --loglevel silent
            '';
        };
      }
    );
}
```

I enter the Nix shell by running `nix develop` but the end result is similar to before, i.e. I get access to the dependencies you see listed in `packages`.

## Conclusion

Nix has a steep learning curve, it takes a while to learn to use and even longer to understand, and it may not be needed for every Elm project. However, I hope that the little taste of Nix that I've given you has piqued your interests.

BTW, feel free to use my `shell.nix` or `flake.nix` files and tweak them to suit your needs.

Happy Nixing!