| name | dev-flake |
| description | Scaffolds and updates Nix flake dev environments including flake.nix, devShells, .envrc, process-compose services, and pre-commit hooks. Use when creating a new flake, adding services (PostgreSQL, Redis, Kafka) to an existing flake, modernizing a dev shell, or any task involving flake.nix, nix develop, or nix flake. Use when this capability is needed. |
| metadata | {"author":"addg0"} |
When to Use
- Setting up a new project's dev environment
- Adding local services (PostgreSQL, Redis, Kafka) to an existing flake
- Fixing or modernizing a project's Nix dev shell
Required Files
project/
├── flake.nix
├── flake.lock # auto-generated
└── .envrc # always just: use flake
flake.nix Template
{
description = "Project Name";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
git-hooks-nix = {
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
process-compose-flake.url = "github:Platonic-Systems/process-compose-flake";
services-flake.url = "github:juspay/services-flake";
};
outputs = inputs @ {flake-parts, ...}:
flake-parts.lib.mkFlake {inherit inputs;} {
systems = ["x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin"];
imports = [
inputs.git-hooks-nix.flakeModule
inputs.process-compose-flake.flakeModule
];
perSystem = {pkgs, config, ...}: let
# Override language toolchains here
java = pkgs.jdk21;
gradle = pkgs.gradle.override {inherit java;};
in {
# Local services: `nix run .#services`
process-compose."services" = {
imports = [inputs.services-flake.processComposeModules.default];
settings.processes = {
pg.shutdown.timeout_seconds = 5;
redis.shutdown.timeout_seconds = 5;
};
services = {
postgres."pg" = {
enable = true;
port = 5432;
listen_addresses = "127.0.0.1";
initialDatabases = [{name = "mydb";}];
};
redis."redis" = {
enable = true;
port = 6379;
bind = "127.0.0.1";
};
};
};
pre-commit.settings.hooks = {
alejandra.enable = true; # always
# google-java-format.enable = true; # Java projects
# prettier.enable = true; # JS/TS projects
};
devShells.default = pkgs.mkShell {
packages = with pkgs; [
# Add project-specific tools here
];
env = {
# Static environment variables go here
# JAVA_HOME = "${java}";
};
shellHook = ''
${config.pre-commit.installationScript}
'';
};
};
};
}
Conventions
- Pin nixpkgs to a release branch (e.g.,
nixos-25.11)
follows nixpkgs on inputs that support it to reduce closure size
- Shutdown timeouts on all process-compose services to prevent hangs
- All tools via Nix — no global installs, no wrapper scripts (e.g., use
gradle not ./gradlew)
- Prefer
env = { } over shellHook exports — use mkShell's env attr for static environment variables (e.g., JAVA_HOME, UV_NO_SYNC). Reserve shellHook for commands that must run at shell entry (e.g., pre-commit.installationScript, unset, dynamic values like $(git rev-parse ...))
- Omit
process-compose-flake and services-flake inputs if no local services needed
Commands
| Command | Purpose |
|---|
direnv allow | Enable environment (one-time) |
nix develop | Enter dev shell manually |
nix run .#services | Start local services |
nix flake update | Update all inputs |
nix flake lock --update-input <name> | Update single input |
Language References
When the project uses a specific language ecosystem, load the corresponding reference for inputs, patterns, and conventions:
Steps
- Ask what language/framework and what local services are needed
- Scaffold
flake.nix from the base template, trimming unused sections
- If a language reference exists, load it and merge those inputs/patterns into the flake
- Add language-specific packages to
devShells.default.packages
- Add appropriate pre-commit hooks for the language
- Configure services if needed, otherwise remove process-compose inputs
- Create
.envrc with use flake
- Run
nix flake lock to generate the lock file
Converted and distributed by TomeVault — claim your Tome and manage your conversions.