Skip to content
Oeiuwq Faith Blog OpenSource Porfolio

arnarg/nix-gleam

Generic nix builder for gleam applications

arnarg/nix-gleam.json
{
"createdAt": "2023-04-14T10:10:23Z",
"defaultBranch": "main",
"description": "Generic nix builder for gleam applications",
"fullName": "arnarg/nix-gleam",
"homepage": "",
"language": "Nix",
"name": "nix-gleam",
"pushedAt": "2025-12-03T14:05:46Z",
"stargazersCount": 50,
"topics": [],
"updatedAt": "2025-12-05T14:58:48Z",
"url": "https://github.com/arnarg/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.

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).

In flake.nix:

{
description = "My gleam application";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-gleam = {
url = "github:arnarg/nix-gleam";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ nixpkgs, nix-gleam, ... }:
let
inherit (nixpkgs) lib;
forEachSystem = lib.genAttrs lib.systems.flakeExposed;
in
{
packages = forEachSystem (system: {
default = nix-gleam.packages.${system}.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 = ./.;
};
});
};
}

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";
nix-gleam = {
url = "github:arnarg/nix-gleam";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ nixpkgs, nix-gleam, ... }:
let
inherit (nixpkgs) lib;
forEachSystem = lib.genAttrs lib.systems.flakeExposed;
in
{
packages = forEachSystem (system:
let
inherit (nix-gleam.packages.${system}) buildGleamApplication;
in
{
# Backend application
backend = buildGleamApplication {
src = ./backend;
# Inform the builder to use `./shared`
# as a local package.
localPackages = [./shared];
};
# Frontend application
frontend = buildGleamApplication {
src = ./frontend;
# Inform the builder to use `./shared`
# as a local package.
localPackages = [./shared];
};
}
);
};
}

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";
nix-gleam = {
url = "github:arnarg/nix-gleam";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ nixpkgs, nix-gleam, ... }:
let
inherit (nixpkgs) lib;
forEachSystem =
f:
lib.genAttrs (import systems) (
system:
f {
inherit system;
pkgs = nixpkgs.legacyPackages.${system};
}
);
in
{
packages = forEachSystem ({ pkgs, system} : {
default = nix-gleam.packages.${system}.buildGleamApplication {
src = ./.;
# Overrides the rebar3 package used, adding
# plugins using `rebar3WithPlugins`.
rebar3Package = pkgs.rebar3WithPlugins {
plugins = with pkgs.beamPackages; [pc];
};
};
});
};
}