Skip to content
Oeiuwq Faith Blog OpenSource Porfolio

esselius/squish-find-the-brains

Nix wrapper for SBT

esselius/squish-find-the-brains.json
{
"createdAt": "2025-11-29T23:10:06Z",
"defaultBranch": "main",
"description": "Nix wrapper for SBT",
"fullName": "esselius/squish-find-the-brains",
"homepage": null,
"language": null,
"name": "squish-find-the-brains",
"pushedAt": "2025-11-21T11:02:17Z",
"stargazersCount": 1,
"topics": [],
"updatedAt": "2025-11-30T00:58:37Z",
"url": "https://github.com/esselius/squish-find-the-brains"
}

CI License: MIT Nix Nix Flake

Reusable Nix flake for building sbt projects with lockfile-based dependency management.

This flake provides a two-phase approach to building sbt projects in Nix:

  1. Lockfile generation: Run sbt with network access to discover dependencies, then generate a lockfile with SHA256 hashes
  2. Offline build: Use the lockfile to fetch dependencies as content-addressed Nix store paths, then build in offline mode

This approach avoids fixed-output derivations (FODs) and provides fully reproducible builds.

{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
squish-find-the-brains.url = "github:7mind/squish-find-the-brains";
};
outputs = { self, nixpkgs, flake-utils, squish-find-the-brains }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
};
coursierCache = squish-find-the-brains.lib.mkCoursierCache {
inherit pkgs;
lockfilePath = ./deps.lock.json;
};
sbtSetup = squish-find-the-brains.lib.mkSbtSetup {
inherit pkgs coursierCache;
};
in
{
packages.default = pkgs.stdenv.mkDerivation {
pname = "my-app";
version = "1.0.0";
src = ./.;
nativeBuildInputs = sbtSetup.nativeBuildInputs;
inherit (sbtSetup) JAVA_HOME;
buildPhase = ''
${sbtSetup.setupScript}
sbt --batch compile assembly
'';
installPhase = ''
mkdir -p $out/lib
cp target/scala-*/my-app.jar $out/lib/
'';
};
}
);
}

Create lockfile-config.json:

{
"sbt_runs": [
{"args": [";reload plugins; update; reload return"]},
{"args": ["+update", "+compile"]}
]
}

the {"args": [";reload plugins; update; reload return"]}, line is especially important to make sure all the plugins were pulled in.

Terminal window
nix run github:7mind/squish-find-the-brains -- lockfile-config.json > deps.lock.json
Terminal window
nix build

Builds a Coursier cache from a lockfile.

squish-find-the-brains.lib.mkCoursierCache {
pkgs = pkgs; # required: nixpkgs package set
lockfilePath = ./deps.lock.json; # required: path to lockfile
}

Returns a derivation containing the reconstructed Coursier cache.

Generates sbt setup configuration for use in custom derivations.

squish-find-the-brains.lib.mkSbtSetup {
pkgs = pkgs; # required: nixpkgs package set
coursierCache = coursierCache; # required: from mkCoursierCache
jdk = pkgs.jdk21; # optional: JDK to use (default: jdk21)
extraSbtOpts = ""; # optional: additional SBT_OPTS
}

Returns an attrset with:

  • setupScript: shell script to set up sbt environment
  • nativeBuildInputs: packages needed for building (sbt, jdk, which)
  • JAVA_HOME: path to JDK

Creates a development shell for sbt projects.

squish-find-the-brains.lib.mkSbtShell {
pkgs = pkgs; # required: nixpkgs package set
jdk = pkgs.jdk21; # optional: JDK to use
extraPackages = []; # optional: additional packages
shellHook = ""; # optional: additional shell hook
}

The lockfile is a JSON file with the following structure:

{
"version": 1,
"artifacts": [
{
"url": "https://repo1.maven.org/maven2/...",
"sha256": "base32-encoded-hash"
}
]
}
Terminal window
# Enter development shell
nix develop
# Generate lockfile
python scripts/generate-lockfile.py lockfile-config.json > deps.lock.json
# Build
nix build

The test/ directory contains a sample project demonstrating usage:

Terminal window
cd test
# Generate lockfile
nix develop ..#default --command python ../scripts/generate-lockfile.py lockfile-config.json > deps.lock.json
# Build with local squish-find-the-brains
nix build --override-input squish-find-the-brains path:..
# Run
./result/bin/squish-find-the-brains-test

sbt-derivation is another approach to building sbt projects in Nix. It uses a fixed-output derivation (FOD) to fetch dependencies, which has different trade-offs:

sbt-derivation (FOD approach):

  • Simpler setup - no lockfile generation step
  • Dependencies fetched in a single FOD
  • Hash must be updated when dependencies change
  • Less granular caching

squish-find-the-brains (lockfile approach):

  • Each dependency is a separate content-addressed derivation
  • Better caching - unchanged dependencies are reused
  • Lockfile provides visibility into exact dependencies
  • Requires lockfile generation step

Choose based on your needs:

  • Use sbt-derivation for simpler projects or when you prefer less setup
  • Use squish-find-the-brains for better caching, reproducibility, and dependency visibility

MIT