Skip to content

Add a Nix flake #16

Description

@tburny

Would you accept a PR adding a flake.nix exposing the allium CLI and the allium-lsp server as Nix packages, plus a dev shell?

Why

I want to pin allium and allium-lsp in a devenv.sh setup. The LSP matters because LSP-to-MCP bridges (e.g. mcp-language-server) let AI agents consume Allium's diagnostics, hovers, and cross-references as structured data instead of parsing CLI stdout — far more useful for spec-shaped languages with cross-references between rules and entities than for general code.

Today, Nix users have to either build from source by hand or vendor a custom derivation. A first-party flake gives a single reproducible install path tied to the repo's release tags.

What it would look like for consumers

Ad-hoc usage:

# Run the CLI without installing
nix run github:juxt/allium-tools -- check spec.allium

# Drop into a shell with allium + allium-lsp on $PATH
nix shell github:juxt/allium-tools

# Install into a user profile
nix profile install github:juxt/allium-tools

Pinned in a downstream flake:

{
  inputs.allium-tools.url = "github:juxt/allium-tools/v3.2.3";

  outputs = { self, nixpkgs, allium-tools, ... }: {
    # ...
    devShell = nixpkgs.legacyPackages.x86_64-linux.mkShell {
      packages = [
        allium-tools.packages.x86_64-linux.allium
        allium-tools.packages.x86_64-linux.allium-lsp
      ];
    };
  };
}

Inside a devenv.nix (my actual use case):

{ pkgs, inputs, ... }: {
  packages = [
    inputs.allium-tools.packages.${pkgs.system}.allium
    inputs.allium-tools.packages.${pkgs.system}.allium-lsp
  ];

  # Editor or MCP-LSP bridge can now spawn `allium-lsp` directly,
  # no Node runtime needed in the project's devenv.
}

For contributors to allium-tools itself:

git clone https://github.com/juxt/allium-tools && cd allium-tools
nix develop      # rustc + wasm-pack + Node 20 + npm + pre-commit, ready to go
cargo test
npm run build

Why this is mostly cheap

Looked at the build inputs first. The CLI is the easy half:

  • crates/allium is pure Rust (serde, regex-lite, serde_json), no build.rs, no FFI, no system libs. rustPlatform.buildRustPackage against the existing Cargo.lock is enough.
  • CI already cross-compiles to x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin (release-artifacts.yml) — same set as flake-utils.lib.defaultSystems.
  • No existing flake.nix / shell.nix / .envrc to conflict with.

The LSP is the real engineering work: it requires wasm-pack to produce packages/allium-parser-wasm/, then buildNpmPackage over the npm workspace consuming that artifact. Tractable, but the wasm-pack ↔ wasm-bindgen-cli version pinning is a known sharp edge in nixpkgs.

The change is purely additive — no edits to Cargo.toml, package.json, scripts, or workflows.

Proposed scope

Split across two PRs to keep review manageable:

PR 1 — CLI + dev shell:

  • packages.allium / packages.default — CLI from crates/allium.
  • apps.default — wires nix run to the CLI.
  • devShells.default — rustc stable + wasm32-unknown-unknown + wasm-pack + Node 20 + npm + pre-commit, matching what .github/workflows/ci.yml installs.

PR 2 — LSP:

  • packages.allium-parser-wasm — wasm-pack output as a Nix derivation.
  • packages.allium-lspbuildNpmPackage consuming the WASM derivation.

VS Code extension .vsix packaging is out of scope; VS Code installs .vsix directly.

Blast radius

Net-new files only: flake.nix, flake.lock. No existing files modified. cargo build, npm run build, CI, release pipeline, pre-commit, and Homebrew distribution are all untouched. Reversible with git rm.

Questions before I start

  1. Preference on flake-parts vs flat flake-utils? I'll default to flake-parts if you don't mind.
  2. Toolchain source: plain nixpkgs rustc (matches CI's dtolnay/rust-toolchain@stable), or pin via rust-overlay / fenix? I'd lean nixpkgs to avoid an extra flake input.

Happy to send the PRs if there's interest.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions