How I use Devbox in my Elm projects
Tags: devbox, elm, webdev
Published: 2024-05-03 01:35:58

---
title: How I use Devbox in my Elm projects
published: true
description: I share how I use Devbox in my Elm projects.
tags: devbox, elm, webdev
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-05-03 01:31 +0000
---

Before I went on my Christmas vacation last year I wrote an article on [how I use Nix in my Elm projects](https://dev.to/dwayne/how-i-use-nix-in-my-elm-projects-5h42). At the time, I was pleased with my set up. However, not even a month would go by before my satisfaction was questioned. In early January, Carlo Ascani asked [a question](https://discourse.elm-lang.org/t/trying-to-get-my-head-around-commands/9586), on the Elm Discourse, about his [Umbra](https://github.com/carlotm/umbra) project. I decided to explore his project and I soon discovered two files, `devbox.json` and `devbox.lock`, I had never seen before. This piqued my curiosity and I had to learn more. I followed the link to the [Devbox website](https://www.jetify.com/devbox/) and feverishly read the [docs](https://www.jetify.com/devbox/docs/). I... was... hooked. I was pleasantly surprised by its simplicity and it seemed to fit my use cases really well.

## What is Devbox?

Devbox is a tool that creates isolated, reproducible development environments that run anywhere. It's based on Nix but no Nix knowledge is required. It's approachable and intuitive.

## How I use Devbox in my Elm projects

I've been using Devbox in the same way I was using [Nix flakes in my Elm projects](https://dev.to/dwayne/how-i-use-nix-in-my-elm-projects-5h42). The major difference, as you'd see in the example below, is that there's much less noise in the configuration.

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
            '';
        };
      }
    );
}
```

Here's the corresponding `devbox.json`.

```json
{
  "packages": {
    "caddy": {
      "version": "latest",
      "disable_plugin": true
    },
    "elmPackages.elm": "latest",
    "elmPackages.elm-doc-preview": "latest",
    "elmPackages.elm-format": "latest",
    "elmPackages.elm-optimize-level-2": "latest",
    "elmPackages.elm-test": "latest",
    "nodejs_20": "latest",
    "nodePackages.terser": "latest",
    "shellcheck": "latest"
  },
  "env": {
    "project": "$PWD",
    "build": "$PWD/.build",
    "PATH": "$PWD/bin:$PATH"
  },
  "shell": {
    "init_hook": [
      "npm install --loglevel silent"
    ]
  }
}
```

## More examples

### freeCodeCamp

I converted all my [freeCodeCamp](https://www.freecodecamp.org/) [Front End Development Libraries Projects](https://www.freecodecamp.org/learn/front-end-development-libraries#front-end-development-libraries-projects) from Nix flakes to use Devbox.

- [Random Quote Machine](https://github.com/dwayne/elm-random-quote-machine/tree/85ff5ec836a81152d65adc39f2752980438b083a)
- [Markdown Previewer](https://github.com/dwayne/elm-markdown-previewer/tree/e2011a3159a958c548af5366796a43a638de6a34)
- [Drum Machine](https://github.com/dwayne/elm-drum-machine/tree/85ed89017d1ac141a3e2f01f6e80ea1cbc261808)
- [Calculator](https://github.com/dwayne/elm-calculator/tree/09d42d31a6b197f8c9c478f39fc87c59644a0acd)
- [25 + 5 Clock](https://github.com/dwayne/elm-pomodoro-clock/tree/09a50b3db1a25804cc5fb1f2698b97a86d27e950)

These projects use [Caddy](https://caddyserver.com/) as my local development server, [Dart Sass](https://sass-lang.com/dart-sass/) for converting my Sass files to CSS, `elm`, `elm-format`, `elm-optimize-level-2`, `elm-review`, `elm-test` (only in [Calculator](https://github.com/dwayne/elm-calculator/tree/09d42d31a6b197f8c9c478f39fc87c59644a0acd)), [ShellCheck](https://www.shellcheck.net/) to find bugs in my shell scripts, and [Terser](https://terser.org/) to mangle and compress JavaScript code.

### [dwayne/elm-hello](https://github.com/dwayne/elm-hello/tree/c03bc8be4759d8abb48fdef415486692d61cc79a)

This project uses [HTMLMinifier](https://github.com/kangax/html-minifier), [optipng](https://optipng.sourceforge.net/), and [zopfli](https://github.com/google/zopfli) to create a custom production Elm build pipeline. You can see how I make use of these tools in this [build](https://github.com/dwayne/elm-hello/blob/c03bc8be4759d8abb48fdef415486692d61cc79a/bin/build) script. Here are [the results](https://github.com/dwayne/elm-hello/tree/6fe317ab54ec8ff7ee747d0fc1737e5199701b1c) in case you're interested. I used the same ideas from this project to build and deploy [dwayne/elm-conduit](https://github.com/dwayne/elm-conduit/tree/69b1cf41d38e34c4bd8b61490d28e224a0481ac2), which you can learn more about in my article [Yet Another Tour of an Open-Source Elm SPA](https://dev.to/dwayne/yet-another-tour-of-an-open-source-elm-spa-1672).

## Finding Nix packages

[Nixhub.io](https://www.nixhub.io/) is a user-friendly website built for Devbox that makes it easy for you to find the right Nix package for your project.

## Conclusion

With little to no learning curve, Devbox is easy to use and it's been a valuable addition to my Elm development workflow. I'm happy to have found it.