2026-03-07 07:49:40 +01:00
2026-03-07 07:49:40 +01:00
2026-03-07 07:39:39 +01:00
2026-03-07 07:42:44 +01:00
2026-03-04 05:32:21 +01:00
2026-03-04 07:25:31 +01:00
2026-03-04 05:07:26 +01:00
2026-03-04 04:58:55 +01:00
2026-03-07 07:39:39 +01:00
2026-03-07 07:39:39 +01:00
2026-03-07 07:49:40 +01:00

repo-lib

repo-lib is a pure-first Nix flake library for repo-level developer workflows:

  • mkRepo for devShells, checks, formatter, and optional packages.release
  • structured tool banners driven from package-backed tool specs
  • structured release steps (writeFile, replace, run)
  • a minimal starter template in template/

Prerequisites

  • Nix with flakes enabled
  • direnv (recommended)

Use the template

nix flake new myapp -t 'git+https://git.dgren.dev/eric/nix-flake-lib?ref=v2.1.0#default' --refresh

Use the library

Add this flake input:

inputs.repo-lib.url = "git+https://git.dgren.dev/eric/nix-flake-lib?ref=v2.1.0";
inputs.repo-lib.inputs.nixpkgs.follows = "nixpkgs";

Build your repo outputs from mkRepo:

outputs = { self, nixpkgs, repo-lib, ... }:
  repo-lib.lib.mkRepo {
    inherit self nixpkgs;
    src = ./.;

    config = {
      checks.tests = {
        command = "echo 'No tests defined yet.'";
        stage = "pre-push";
        passFilenames = false;
      };

      release = {
        steps = [ ];
      };
    };

    perSystem = { pkgs, system, ... }: {
      tools = [
        (repo-lib.lib.tools.fromPackage {
          name = "Nix";
          package = pkgs.nix;
          version.args = [ "--version" ];
        })
      ];

      shell.packages = [
        self.packages.${system}.release
      ];
    };
  };

mkRepo generates:

  • devShells.${system}.default
  • checks.${system}.pre-commit-check
  • formatter.${system}
  • packages.${system}.release when config.release != null
  • merged packages and apps from perSystem

Tool banners

Tools are declared once, from packages. They are added to the shell automatically and rendered in the startup banner.

(repo-lib.lib.tools.fromPackage {
  name = "Go";
  package = pkgs.go;
  version.args = [ "version" ];
  banner.color = "CYAN";
})

Required tools fail shell startup if their version probe fails. This keeps banner output honest instead of silently hiding misconfiguration.

Purity model

The default path is pure: declare tools and packages in Nix, then let mkRepo assemble the shell.

Impure bootstrap work is still possible, but it must be explicit:

config.shell = {
  bootstrap = ''
    export GOBIN="$PWD/.tools/bin"
    export PATH="$GOBIN:$PATH"
  '';
  allowImpureBootstrap = true;
};

Release steps

Structured release steps are preferred over raw sed snippets:

config.release = {
  steps = [
    {
      writeFile = {
        path = "src/version.ts";
        text = ''
          export const APP_VERSION = "$FULL_VERSION" as const;
        '';
      };
    }
    {
      replace = {
        path = "README.md";
        regex = ''^(version = ")[^"]*(")$'';
        replacement = ''\1$FULL_VERSION\2'';
      };
    }
    {
      run = {
        script = ''
          echo "Released $FULL_TAG"
        '';
      };
    }
  ];
};

The generated release command still supports:

release
release patch
release beta
release minor beta
release stable
release set 1.2.3

Low-level APIs

mkDevShell and mkRelease remain available for repos that want lower-level control or a migration path from the older library shape.

Common command

nix fmt
Description
Personal lib for bootstrapping repositories
Readme 16 MiB
Languages
Go 60.9%
Nix 32.7%
Shell 6.4%