Nix Best Practises
What This Skill Does
Provides conventions to follow when a project has (or needs) a flake.nix defining its OS-level tool dependencies.
Rules
1. Prefer nested attribute sets over dotted paths
Don't chain config with . — keep nested {} instead.
# Good
nixpkgs = {
url = "github:nixos/nixpkgs?ref=26.05";
};
# Avoid
nixpkgs.url = "something";
2. Required buildInputs
Every flake must include these in buildInputs:
nixdnixfmt-rfc-style
3. Custom derivations go in nix/derivations
Keep derivations of custom packages under nix/derivations and link them from flake.nix — don't inline custom derivations directly in flake.nix.
4. Keep the flake description minimal
description should be as small as possible — just the project name and its purpose (api, cli, ui, etc.), not a full explanation.
5. Pair every flake.nix with an .envrc
Every project with a flake.nix gets a matching .envrc for direnv, so the devShell activates automatically on cd:
dotenv .env
use flake
dotenv .envcomes first if the project has a.envfile — omit it if there's none.use flakeis the default; add--impure(use flake . --impure) only if the flake actually needs it (e.g. it reads env vars or impure paths at eval time).
Quick Checklist
When creating or reviewing a flake.nix:
- Attribute sets use nested
{}, not dotted chains -
buildInputsincludesnixdandnixfmt-rfc-style - Custom derivations live in
nix/derivationsand are linked in, not inlined -
descriptionis short: name + purpose only - A matching
.envrcexists withuse flake(plusdotenv .envif applicable)