A rewrite of cachix/elm2nix with a few changes and improvements.
These are some of the notable differences:
- You can input one or more
elm.jsonfiles to create the lock file. - It uses a JSON formatted lock file that has support for multiple versions of the same package.
- You don't have to manually generate a
registry.datfile since it's automatically handled for you. - You can display any
registry.datfile as JSON usingelm2nix registry view. - There is a
buildElmApplicationbuild helper that allows you to build an Elm application in a variety of ways by setting options. For e.g.- Turn on the time-travelling debugger
- Fail the build if your Elm source code is improperly formatted
- Fail the build if your Elm tests fail
- Fail the build if
elm-reviewfails - Turn on optimizations
- Use
elm-optimize-level-2instead ofelm make --optimize - Enable minification with UglifyJS or Terser
- Enable compression with gzip and brotli
- Show a report about the changes in your file size due to minification and compression
- Enable content hashing for cache busting purposes
- Or completely customize portions of the build to your liking if you know how
stdenv.mkDerivationworks
In the folder containing your Elm application's elm.json you use:
elm2nix lockto generate anelm.locklock file
The lock file is used by a build helper, called buildElmApplication, to build your Elm application.
- Add
dwayne/elm2nixas an input to your flake.
inputs.elm2nix.url = "github:dwayne/elm2nix";- Add it's default package to your development shell.
outputs = { self, nixpkgs, flake-utils, elm2nix }:
flake-utils.lib.eachDefaultSystem(system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
packages = [
elm2nix.packages.${system}.default
...
];
...
};
...
}
);- Use the
elm2nixprogram to generate theelm.lockfile from your Elm application'selm.json.
nix develop
elm2nix lockSee elm2nix lock --help for more details.
- Use
buildElmApplicationto build your Elm application.
outputs = { self, nixpkgs, flake-utils, elm2nix }:
flake-utils.lib.eachDefaultSystem(system:
let
pkgs = nixpkgs.legacyPackages.${system};
inherit (elm2nix.lib.elm2nix pkgs) buildElmApplication;
myApp = buildElmApplication {
name = "my-app";
src = ./.;
elmLock = ./elm.lock;
};
in
{
packages.myApp = myApp;
...
}
);- Build your Elm application.
nix build .#myAppThis will generate a result/ directory containing your compiled application in elm.js.
- That's it.
You can view a full working example in the example/ directory.
I was looking for a practical and interesting project to work on that might be beneficial to either the Elm or Haskell community, while at the same time, would extend my skills within functional programming. When I researched cachix/elm2nix it seemed to fit the bill because it combined 3 technologies I love, Elm, Haskell, and Nix, to produce a useful tool for Elm developers. At the time, I knew how to use each of the technologies to varying degrees but I didn't have a deep understanding of how cachix/elm2nix worked and why it needed to work that way. As a result, it seemed like a great project to satisfy my goals. Thankfully it turned out well. I learned so much about Elm, Haskell, and Nix that I didn't know before and I was able to find little ways to positively improve upon the project.
A grossly incomplete list of resources that helped me while working on the project.