Nixfied lets a project describe its services, tasks, and exported workflows
once in typed Nix. Nix evaluates and builds those declarations into a canonical
project manifest, manifest.json; a generic, Nix-free Rust runtime then owns
process execution, ports, state, recovery, and cleanup.
The manifest has two kinds:
- a task is an invocation with an optional deadline or a static composite DAG;
- a service is a runtime-owned long-lived process with lifecycle and optional endpoint declarations.
Projects name those primitives in their own vocabulary—lint, database,
dev, test, release—without adding domain logic to the runtime. Several
isolated slots can run side by side with separate ports, processes, and state.
The only prerequisite is Nix with flakes enabled. Inspect Nixfied's own runnable apps without a checkout:
nix run github:willyrgf/nixfied#helpThe catalog is reference-neutral. Reuse the same flake reference with a listed
name, for example nix run github:willyrgf/nixfied#check.
In a project that does not already have a flake.nix, run:
nix run github:willyrgf/nixfied#install -- \
--project-id my-project \
--name "My Project"The installer creates:
flake.nix, which declares Nixfied and exposes the compiled manifest and generated apps;nixfied.nix, which the project owns and edits.
It starts with a synthetic service and exported smoke task, so the complete
path is immediately runnable. In a Git worktree, stage flake.nix and
nixfied.nix before locking, then commit them with the generated flake.lock:
git add flake.nix nixfied.nix # Git worktrees only: expose new sources to Nix
nix flake lock # pin the declared inputs
git add flake.lock # Git worktrees only: include the pin in the commit
nix run .#help # list Nixfied-generated commands and their purpose
nix run .#docs # read the reference at this project's Nixfied revision
nix build .#manifest # evaluate, validate, and compile the manifest
nix run .#manifest-check # admit it without executing a task
nix run .#smoke # run the starter's exported taskThe default input URL tracks Nixfied; flake.lock pins the exact revision.
See upgrade and recovery for routine upgrades
and switching a commit-pinned input to tracking once.
Replace the starter declarations with your services and workflows. Existing
flakes are supported through the same compileManifest and projectApps calls;
the installer refuses to edit an existing flake.nix and prints the merge
fragment instead.
The distribution boundary is deliberate: .#install is a CLI-only scaffold
wrapper and does not depend on the process runtime. Runtime-backed project apps
use the release nixfied-runtime package; inspect their command relationships with
nix run .#docs -- api app project/run. The debug runtime and test child are
private framework-check inputs, not adopter-facing package outputs.
See the adopter guide for existing-flake integration, the authoring model, command semantics, slots and state, secrets, adapters, and upgrades.
- Nix is the public integration and correctness layer. Typed modules reject invalid intent and realise every executable closure.
- Rust is the hidden impure runtime. It admits the compiled manifest, starts and stops session-owned process groups, recovers interrupted sessions, checks managed listeners and application probes, and safely cleans runtime-owned state. It never invokes Nix.
manifest.jsonis the only semantic seam. Itsviews/docs.mdfile is a disposable, manifest-derived human reference.
Nixfied owns:
- task and service execution;
- process containment and cancellation;
- service state and lifecycle;
- declared endpoint placement, managed listener observation and application probes;
- runtime-owned run evidence;
- marker-gated, path-confined cleanup of state roots it owns.
Independent clients can use context, observe, and ensure to share one
declared service owner. Ensure fully admits and matches the request, then waits
for canonical root task evidence and fresh leader identities. Canceling an
observer leaves a committed shared owner running; down stops it explicitly.
See sharing a service owner.
Compiler and tool caches remain child-, tool-, and project-owned. Nixfied does not own their:
- placement or compatibility policy;
- writer arbitration;
- inventory, timestamps, or byte accounting;
- retention or eviction policy;
- corruption recovery;
- cold/warm modes;
- operator history.
Build the manifest to inspect the exact tasks, services, slots, port windows, and state policy of an adopted project:
nix build .#manifest
less result/views/docs.md- Adopter guide — installation, integration, authoring, operations, upgrades, and project documentation boundaries.
- Option reference — generated
nixfied.nixoption types, defaults, and descriptions. - Adapter guide — adapter authoring and endpoint conventions.
- Contract — normative manifest, lifecycle, state, and output behavior.
- Architecture — rationale and product boundaries.
- Development guide — repository layout, checks, gates, and test placement.
- Derivation specification — canonical graph facts derived independently by Nix and Rust.
| Example | Demonstrates |
|---|---|
minimal |
Smallest service and task |
postgres |
Postgres adapter lifecycle and smoke query |
reth |
Multi-endpoint Reth adapter and JSON-RPC probe |
composite |
Static task DAG over a service |
downstream |
Realistic database, API, worker, and release flow |
toolchain |
Heterogeneous tools, nested composites, and an endpoint-less worker |
For example:
nix build --no-write-lock-file ./examples/downstream#manifestRun nix run .#help to list the framework repository commands. The canonical
local repository gate is:
nix run .#ciIt runs the source and build checks, white-box Cargo tests, and both integration gates. Use the development guide for focused checks and the exact coverage of each stage.