Home

Awesome

nix-gleam

Generic nix builder for gleam applications.

Gleam will create a manifest.toml file for every project which acts as a lock file and contains package name, version and a sha256 checksum of the package for every dependency. This is enough info for the builder to fetch all dependencies using fetchHex in nix.

Usage

Currently there is only 1 builder which builds a gleam application and supports both erlang and javascript target (but hard-coded to use nodejs runtime).

buildGleamApplication

In flake.nix:

{
  description = "My gleam application";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.nix-gleam.url = "github:arnarg/nix-gleam";

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    nix-gleam,
  }: (
    flake-utils.lib.eachDefaultSystem
    (system: let
      pkgs = import nixpkgs {
        inherit system;
        overlays = [
          nix-gleam.overlays.default
        ];
      };
    in {
      packages.default = pkgs.buildGleamApplication {
        # The pname and version will be read from the `gleam.toml`
        # file generated by gleam.
        # But this can be overwritten here too:
        # pname = "my-app";
        # version = "1.2.3";

        # The target is read from the `gleam.toml` file too.
        # Default is "erlang" if nothing is specified but
        # this can also be overwritten here too:
        # target = "javascript";

        # Erlang package can be overridden but defaults to
        # `pkgs.erlang`.
        # erlangPackage = pkgs.erlang_nox;

        src = ./.;
      };
    })
  );
}

Examples

Monorepo

In a monorepo example where sub-directories backend, frontend and shared are all different gleam packages where backend and frontend have a local path dependency shared, the following flake.nix can be used in the root of the monorepo.

{
  description = "My gleam monorepo";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.nix-gleam.url = "github:arnarg/nix-gleam";

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    nix-gleam,
  }: (
    flake-utils.lib.eachDefaultSystem
    (system: let
      pkgs = import nixpkgs {
        inherit system;
        overlays = [
          nix-gleam.overlays.default
        ];
      };
    in {
      packages = {
        # Backend application
        backend = pkgs.buildGleamApplication {
          src = ./backend;
          # Inform the builder to use `./shared`
          # as a local package.
          localPackages = [./shared];
        };
        # Frontend application
        frontend = pkgs.buildGleamApplication {
          src = ./frontend;
          # Inform the builder to use `./shared`
          # as a local package.
          localPackages = [./shared];
        };
      };
    })
  );
}

Rebar3 plugins

Some dependencies will take in erlang dependencies that might need rebar3 plugins to build and will produce build errors like:

Errors loading plugin pc. Run rebar3 with DEBUG=1 set to see errors.

In such cases rebar3 package used in the build can be overwritten with rebar3Package.

{
  description = "My gleam application";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.nix-gleam.url = "github:arnarg/nix-gleam";

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    nix-gleam,
  }: (
    flake-utils.lib.eachDefaultSystem
    (system: let
      pkgs = import nixpkgs {
        inherit system;
        overlays = [
          nix-gleam.overlays.default
        ];
      };
    in {
      packages.default = pkgs.buildGleamApplication {
        src = ./.;

        # Overrides the rebar3 package used, adding
        # plugins using `rebar3WithPlugins`.
        rebar3Package = pkgs.rebar3WithPlugins {
          plugins = with pkgs.beamPackages; [pc];
        };
      };
    })
  );
}