chore: add Nix dev shells for backend and frontend - #302
Open
FrameAutomata wants to merge 1 commit into
Open
Conversation
This was referenced Aug 25, 2026
FrameAutomata
force-pushed
the
chore/nix-dev-shells
branch
from
August 25, 2026 16:52
51c6063 to
ba7ba00
Compare
Only cli/ had a flake, so backend and frontend work relied on ad-hoc `nix-shell -p go` and whatever node happened to be on PATH. Adds a root flake with four shells: default go + node + the shared tooling backend go + shared, no node frontend node + shared, no go toolchain oxc backend + cargo/rustc for scripts/build-oxc-shim.sh They are split rather than one fat shell because the union closure is ~1.2GB: a frontend-only contributor would otherwise realise ~611MB of Go tooling they never invoke. Toolchain versions are derived from the manifests instead of restated, so they cannot drift: the Go version is read out of backend/go.mod and the node major out of frontend/package.json, which gains the `engines` field it was missing. That field is also the single declaration the node:22-alpine Dockerfiles can be checked against. The shells deliberately export no backend configuration. The backend supplies its own startup defaults, so a dev shell that set DB_TYPE/PORTS would only shadow backend/.env -- godotenv.Load never overwrites an already-set variable -- and would drift from the code it duplicates. JWT_SECRET has no default anywhere on purpose; the backend's own error message is the single source of that instruction. The banner is gated on an interactive shell and interpolates versions at eval time: an unconditional echo lands on stdout ahead of the command in `x=$(nix develop --command ...)`, and probing versions at runtime forks go/node on every shell entry and direnv reload. Also ignores .direnv/, .envrc.local (which .envrc sources for local secrets), nix result symlinks anchored to the working directory, and the local databases the backend writes -- as two globs whose basename must start with `traceway`, so tracked files like Dockerfile.duckdb are unaffected while a DB created from any directory is covered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
FrameAutomata
force-pushed
the
chore/nix-dev-shells
branch
from
August 25, 2026 20:15
ba7ba00 to
242a697
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Only
cli/had a flake. Backend and frontend work relied on ad-hocnix-shell -p goand whatevernodehappened to be onPATH.Shells
defaultbackendfrontendoxcscripts/build-oxc-shim.shSplit rather than one fat shell because the union closure is ~1.2GB — a frontend-only contributor would otherwise realise ~611MB of Go tooling they never invoke.
Versions are derived, not restated
The Go version is read out of
backend/go.modand the node major out offrontend/package.json, which gains theenginesfield it was missing:Bumping either manifest moves the dev shell automatically, so they cannot drift.
engines.nodeis also the single declaration thenode:22-alpineDockerfiles can be checked against — a CI assertion for that is a reasonable follow-up, deliberately not included here.No backend configuration in the shells
Earlier revisions of this PR exported
DB_TYPE,PORTSand a literalJWT_SECRET. All three are gone:DB_TYPEsilently shadowedbackend/.env, sincegodotenv.LoadcallsloadFile(name, false)and never overwrites a set variable#305 fixes it at the source instead. The flake now carries zero backend knowledge, so there is nothing left that can drift from the code.
Other details
The banner is gated on an interactive shell — an unconditional
echoin ashellHooklands on stdout ahead of the command inx=$(nix develop --command ...). Versions interpolate at eval time rather than forkinggo/nodeon every shell entry and direnv reload..gitignoregains.direnv/,.envrc.local(which.envrcsources for local secrets), nixresultsymlinks anchored to the working directory, and the local databases as two globs whose basename must start withtraceway— so a DB created from any directory is covered while tracked files likeDockerfile.duckdbare not.Verification
All five shells evaluate with distinct derivation names and zero backend-env references. Frontend builds clean under node 22.
nixfmt --checkpasses.🤖 Generated with Claude Code