Lockfile Format
go2nix uses TOML lockfiles to pin module hashes. Both builder modes use the same lockfile format.
| Builder | Command | Sections |
|---|---|---|
| Default | go2nix generate | [mod] + [replace] |
| Experimental | go2nix generate | [mod] + [replace] |
Format
Generated by go2nix generate. Both modes use the same lockfile format.
# go2nix lockfile v2. Generated by go2nix. Do not edit.
[mod]
"github.com/foo/bar@v1.2.3" = "sha256-abc..."
"golang.org/x/sys@v0.20.0" = "sha256-def..."
[replace]
"github.com/foo/bar@v1.2.3" = "github.com/fork/bar"
Sections
[mod] — Module hashes. Each key is a composite "path@version" string,
each value is a sha256-... SRI hash of the module’s GOMODCACHE directory.
[replace] — Module replacements (from go.mod replace directives).
Maps the original composite key to the replacement module path. Only
remote replacements are recorded; local replace directives (filesystem
paths) are not included.
Composite keys
Module keys use "path@version" format (e.g., "golang.org/x/sys@v0.20.0").
This keeps each module uniquely identified and avoids collisions across
versions.
Package graph resolution
The lockfile does not contain a package dependency graph. Instead:
- Default mode discovers the package graph at eval time via the
go2nix-nix-plugin (
builtins.resolveGoPackages), which runsgo listagainst the source tree. - Experimental mode discovers the package graph at build time via
go list -json -depsinside a recursive-nix wrapper.
Only module NAR hashes are required in the lockfile (for fixed-output derivations that fetch each module).
Monorepo support
When go2nix generate is given multiple directories, all modules are merged
into a single lockfile. Modules from different go.mod files coexist without
conflict since each is uniquely keyed by "path@version".
Staleness detection
| When | What | Applies to | How |
|---|---|---|---|
| Generation | MVS consistency | All modes | go list -json -deps resolves actual versions |
| Nix eval | Package graph | Default only | builtins.resolveGoPackages runs go list at eval time |
| Build time | Lockfile consistency | Default only | link-binary validates lockfile against go.mod via mvscheck.CheckLockfile |
In the default mode, missing or mismatched modules are caught at build time
when link-binary validates the lockfile. Stale package graph information
is caught at eval time when builtins.resolveGoPackages runs go list.
In the experimental mode, module mismatches surface at build time when
go list or module fetching fails inside the recursive-nix sandbox.
Run go2nix check <dir> or go2nix check --lockfile <path> <dir> to verify
a lockfile without building.