Nix and devenv content site
This is a small content site, and it earns its place here for the development environment rather than the application. It sits outside my main Vue and FastAPI cluster, which is exactly why it is useful: it isolates the environment question from the framework question.
The problem it solved for me is one I keep hitting. package.json pins the application’s dependencies and nothing else. The Node version, the formatter, the language server, and the database the project talks to all live outside that boundary, which means “it works on my machine” survives even a clean npm ci. Six months later I come back to the project and the toolchain has drifted underneath it.
What the setup does
The shell is built with Nix, direnv, and devenv. Entering the directory gives me the Node version the project was written against, the language server and formatter already on PATH, and a project-local PostgreSQL instance that starts and stops with the shell rather than running as a system service.
That last part is the piece I underrated at first. Keeping the database project-local means two projects on the same machine cannot collide on a port or a data directory, and it means the database version is pinned in the same file as everything else.
What I would keep and what I would not
Worth carrying forward:
- Pinning the toolchain in the same commit as the code it builds, so a checkout of an old revision reproduces the environment that revision expected.
- Treating services as part of the development shell, not as machine state.
- A clean split between a content-site setup like this one and a heavier backend stack — trying to make one devenv configuration serve both produces something that serves neither well.
Worth being honest about:
- The first setup costs more than a
Dockerfilewould, and the Nix error messages are genuinely hostile to anyone who has not used it before. This pays off on projects with a long life and irregular attention, which is most of mine, but it is not free. - Anyone else touching the project has to install Nix. On a solo or small project that is a fair trade; on a team that has not opted in, it is not.
See also: Node.js, PostgreSQL, and the web development MOC for where this sits among the other project stacks.