| name | Devenv Ecosystem |
| description | This skill should be used when the user asks to "devenv", "devenv.nix", "languages.*", "services.*", "git-hooks", "devenv shell", "devenv up", "devenv build", or works with devenv development environments. Provides comprehensive devenv configuration patterns. |
| version | 2.0.0 |
Provide comprehensive patterns for devenv configuration, focusing on language setup, services, tooling (git-hooks, scripts, processes), outputs, and profiles.
devenv.nix configuration files and devenv-specific options
Nix language syntax and semantics, flake structure and inputs, general NixOS module patterns, lib.* functions
languages.* language modules, services.* service configuration, git-hooks.hooks pre-commit hooks, processes and native process manager (default in 2.0) or process-compose, scripts and tasks, outputs and profiles, devenv.shells multi-shell configurations (2.0+), devenv.outputs custom flake outputs (2.0+), devenv 2.0 features (interactive TUI, native shell, C FFI backend, incremental eval cache, cross-repo references)
Initialize new devenv project with devenv.nix and .envrc
Enter development shell with all configured tools
Start all configured processes (native process manager by default in 2.0; use process-compose via process.manager.implementation)
Build configured outputs
Run configured tests
Execute configured tasks
Update devenv inputs
Garbage collect unused derivations
Show environment information
Build OCI container images
Main configuration file for devenv environments
{ pkgs, config, ... }:
{
languages.python.enable = true;
packages = [ pkgs.git ];
services.postgres.enable = true;
}
Devenv uses the NixOS module system for configuration
{ pkgs, lib, config, ... }:
{
options.myOption = lib.mkEnableOption "custom option";
config = lib.mkIf config.myOption {
packages = [ pkgs.hello ];
};
}
External flake inputs available in devenv.nix
{ pkgs, inputs, ... }:
{
packages = [ inputs.my-flake.packages.${pkgs.system}.default ];
}
<devenv_20>
devenv 2.0 released March 2026 — "A Fresh Interface to Nix"
Every devenv command now shows a live terminal interface with structured progress: evaluation status, derivation build/download counts, task execution hierarchy, and auto-expanding error details.
Background rebuilds while shell stays interactive. Save a file, devenv rebuilds in background, status line shows progress, Ctrl+Alt+R applies new environment. Errors appear in status line without disruption.
Replaced multiple nix CLI invocations with C FFI backend (nix-bindings-rust). Calls Nix evaluator and store directly through C API instead of spawning separate processes.
Each evaluated attribute cached individually with tracked file/env dependencies. Only changed attributes re-evaluated.
Reference outputs from another devenv project (third most upvoted feature request).
<breaking_changes>
Native process manager is now the default. Set process.manager.implementation = "process-compose" for old behavior.
devenv 0.x is deprecated. Support will be dropped in devenv 3.
</breaking_changes>
</devenv_20>
Enable language support with defaults
languages.python.enable = true;
<pattern name="version_specification">
<description>Specify language version (available for some languages)</description>
<example>
languages.python.version = "3.13";
languages.ruby.version = "3.2.1";
languages.rust.channel = "stable";
</example>
</pattern>
<pattern name="package_override">
<description>Use custom package instead of default</description>
<example>
languages.go.package = pkgs.go_1_26;
languages.java.jdk.package = pkgs.jdk17;
</example>
</pattern>
<pattern name="version_file">
<description>Read version from file (Ruby, Python)</description>
<example>
languages.ruby.versionFile = "./.ruby-version";
languages.python.versionFile = "./.python-version";
</example>
</pattern>
<pattern name="dev_tooling">
<description>Configure LSP, debugger, linter, formatter (devenv 1.8+, enhanced in 2.0)</description>
<example>
languages.rust.dev = {
lsp.enable = true;
debugger.enable = true;
linter.enable = true;
formatter.enable = true;
};
</example>
</pattern>
</common_patterns>
System programming languages (C, C++, Rust, Go, Zig, Nim, Odin, V)
<language name="rust">
<example>
languages.rust = {
enable = true;
channel = "stable"; # or "nightly", "beta"
edition = "2024"; # Rust edition (2015, 2018, 2021, 2024)
components = [ "rustc" "cargo" "clippy" "rustfmt" "rust-analyzer" ];
targets = [ "wasm32-unknown-unknown" ];
};
</example>
<output_pattern>
outputs.rust-app = config.languages.rust.import ./rust-app {};
</output_pattern>
</language>
<language name="go">
<example>
languages.go = {
enable = true;
package = pkgs.go_1_26;
};
</example>
<output_pattern>
outputs.go-app = config.languages.go.import ./go-app {};
</output_pattern>
</language>
<language name="c_cpp">
<example>
languages.c.enable = true;
languages.cplusplus.enable = true;
</example>
</language>
<language name="zig">
<example>
languages.zig = {
enable = true;
package = pkgs.zig;
zls.package = pkgs.zls;
};
</example>
</language>
<language name="nim">
<example>
languages.nim = {
enable = true;
package = pkgs.nim;
};
</example>
</language>
<language name="odin">
<example>
languages.odin = {
enable = true;
package = pkgs.odin;
};
</example>
</language>
<language name="v">
<example>
languages.v = {
enable = true;
package = pkgs.vlang;
};
</example>
</language>
Interpreted languages (Python, Ruby, PHP, Perl, Lua)
<language name="python">
<example>
languages.python = {
enable = true;
version = "3.13";
uv.enable = true;
uv.sync.enable = true;
};
</example>
<poetry_example>
languages.python = {
enable = true;
poetry = {
enable = true;
install.enable = true;
install.allExtras = true;
};
};
</poetry_example>
<output_pattern>
outputs.python-app = config.languages.python.import ./python-app {};
</output_pattern>
</language>
<language name="ruby">
<example>
languages.ruby = {
enable = true;
version = "3.3.0";
bundler.enable = true;
};
</example>
</language>
<language name="php">
<example>
languages.php = {
enable = true;
package = pkgs.php85;
extensions = [ "opcache" "redis" ];
};
</example>
</language>
<language name="perl">
<example>
languages.perl.enable = true;
</example>
</language>
<language name="lua">
<example>
languages.lua.enable = true;
</example>
</language>
JVM languages (Java, Kotlin, Scala, Clojure)
<language name="java">
<example>
languages.java = {
enable = true;
jdk.package = pkgs.jdk21;
maven.enable = true;
gradle.enable = true;
};
</example>
</language>
<language name="kotlin">
<example>
languages.kotlin.enable = true;
</example>
</language>
<language name="scala">
<example>
languages.scala = {
enable = true;
package = pkgs.scala_3;
sbt.enable = true;
};
</example>
</language>
<language name="clojure">
<example>
languages.clojure.enable = true;
</example>
</language>
Functional languages (Haskell, OCaml, Elixir, Erlang, Elm, PureScript)
<language name="haskell">
<example>
languages.haskell = {
enable = true;
languageServer = pkgs.haskell-language-server;
stack = {
enable = true;
args = [ "--no-nix" "--system-ghc" "--no-install-ghc" ];
};
};
</example>
</language>
<language name="ocaml">
<example>
languages.ocaml = {
enable = true;
packages = pkgs.ocaml-ng.ocamlPackages_5_1;
};
</example>
</language>
<language name="elixir">
<example>
languages.elixir.enable = true;
</example>
</language>
<language name="erlang">
<example>
languages.erlang.enable = true;
</example>
</language>
<language name="elm">
<example>
languages.elm.enable = true;
</example>
</language>
<language name="purescript">
<example>
languages.purescript = {
enable = true;
package = pkgs.purescript;
};
</example>
</language>
<language name="gleam">
<example>
languages.gleam.enable = true;
</example>
</language>
<language name="idris">
<example>
languages.idris = {
enable = true;
package = pkgs.idris2;
};
</example>
</language>
<language name="lean4">
<example>
languages.lean4 = {
enable = true;
package = pkgs.lean4;
};
</example>
</language>
<language name="unison">
<example>
languages.unison.enable = true;
</example>
</language>
Web development (JavaScript, TypeScript, Deno)
<language name="javascript">
<example>
languages.javascript = {
enable = true;
package = pkgs.nodejs_24;
npm.enable = true;
npm.install.enable = true;
};
</example>
<pnpm_example>
languages.javascript = {
enable = true;
pnpm.enable = true;
pnpm.install.enable = true;
};
</pnpm_example>
<bun_example>
languages.javascript = {
enable = true;
bun.enable = true;
bun.install.enable = true;
};
</bun_example>
<yarn_example>
languages.javascript = {
enable = true;
yarn.enable = true;
yarn.install.enable = true;
};
</yarn_example>
<corepack_example>
languages.javascript = {
enable = true;
corepack.enable = true;
};
</corepack_example>
</language>
<language name="typescript">
<example>
languages.typescript.enable = true;
</example>
</language>
<language name="deno">
<example>
languages.deno.enable = true;
</example>
</language>
Other languages
<language name="nix">
<example>
languages.nix = {
enable = true;
lsp.package = pkgs.nil; # or pkgs.nixd
};
</example>
</language>
<language name="swift">
<example>
languages.swift.enable = true;
</example>
</language>
<language name="crystal">
<example>
languages.crystal.enable = true;
</example>
</language>
<language name="dart">
<example>
languages.dart.enable = true;
</example>
</language>
<language name="r">
<example>
languages.r.enable = true;
</example>
</language>
<language name="julia">
<example>
languages.julia.enable = true;
</example>
</language>
<language name="fortran">
<example>
languages.fortran.enable = true;
</example>
</language>
<language name="pascal">
<example>
languages.pascal = {
enable = true;
lazarus.enable = true;
};
</example>
</language>
<language name="raku">
<example>
languages.raku.enable = true;
</example>
</language>
<language name="racket">
<example>
languages.racket.enable = true;
</example>
</language>
<language name="standardml">
<example>
languages.standardml.enable = true;
</example>
</language>
<language name="solidity">
<example>
languages.solidity = {
enable = true;
package = pkgs.solc;
};
</example>
</language>
<language name="terraform">
<example>
languages.terraform.enable = true;
</example>
</language>
<language name="opentofu">
<example>
languages.opentofu.enable = true;
</example>
</language>
<language name="ansible">
<example>
languages.ansible = {
enable = true;
package = pkgs.ansible;
};
</example>
</language>
<language name="helm">
<example>
languages.helm = {
enable = true;
languageServer.enable = true;
};
</example>
</language>
<language name="cue">
<example>
languages.cue = {
enable = true;
package = pkgs.cue;
};
</example>
</language>
<language name="jsonnet">
<example>
languages.jsonnet.enable = true;
</example>
</language>
<language name="typst">
<example>
languages.typst = {
enable = true;
fontPaths = [ "${pkgs.roboto}/share/fonts/truetype" ];
};
</example>
</language>
<language name="texlive">
<example>
languages.texlive.enable = true;
</example>
</language>
<language name="gawk">
<example>
languages.gawk.enable = true;
</example>
</language>
<language name="shell">
<example>
languages.shell.enable = true;
</example>
</language>
<language name="robotframework">
<example>
languages.robotframework.enable = true;
</example>
</language>
<language name="vala">
<example>
languages.vala.enable = true;
</example>
</language>
<language name="dotnet">
<example>
languages.dotnet.enable = true;
</example>
</language>
<decision_tree name="language_selection">
What type of project are you building?
Use Rust, Go, Zig, or C/C++
Use JavaScript/TypeScript, Python, Ruby, Go, or Rust
Use JavaScript/TypeScript with npm/pnpm/bun
Use Python with uv or poetry
Use Haskell, OCaml, Elixir, or Gleam
Use Java, Kotlin, or Scala with gradle/maven/sbt
Use Terraform, OpenTofu, Ansible, or Nix
</decision_tree>
<decision_tree name="package_manager_selection">
Which JavaScript/TypeScript package manager to use?
Match existing lock file (package-lock.json=npm, pnpm-lock.yaml=pnpm, yarn.lock=yarn, bun.lockb=bun)
Use pnpm or bun
Use npm (most widely supported)
Use pnpm or yarn with workspaces
Use corepack.enable with packageManager in package.json
</decision_tree>
<decision_tree name="devenv_vs_flakes">
Should you use devenv or pure Nix flakes?
Use devenv - services.* is simpler
Use devenv - git-hooks integration built-in
Use devenv - native process manager (2.0 default) or process-compose
Use devenv - languages.* handles versions
Use flakes - devenv adds overhead
Use flakes - devenv is for dev environments
</decision_tree>
Background services for development environments
services.postgres = {
enable = true;
package = pkgs.postgresql_16;
initialDatabases = [{ name = "myapp"; }];
listen_addresses = "127.0.0.1";
port = 5432;
extensions = [ "postgis" "pgvector" ];
settings = {
max_connections = 100;
};
};
<service name="mysql">
<example>
services.mysql = {
enable = true;
package = pkgs.mysql80;
initialDatabases = [{ name = "myapp"; }];
};
</example>
</service>
<service name="mongodb">
<example>
services.mongodb = {
enable = true;
};
</example>
</service>
<service name="redis">
<example>
services.redis = {
enable = true;
port = 6379;
};
</example>
</service>
<service name="memcached">
<example>
services.memcached = {
enable = true;
};
</example>
</service>
<service name="minio">
<example>
services.minio = {
enable = true;
};
</example>
</service>
<service name="elasticsearch">
<example>
services.elasticsearch = {
enable = true;
};
</example>
</service>
<service name="opensearch">
<example>
services.opensearch = {
enable = true;
};
</example>
</service>
services.rabbitmq = {
enable = true;
};
<service name="kafka">
<example>
services.kafka = {
enable = true;
};
</example>
</service>
services.nginx = {
enable = true;
httpConfig = ''
server {
listen 8080;
location / {
proxy_pass http://localhost:3000;
}
}
'';
};
<service name="caddy">
<example>
services.caddy = {
enable = true;
};
</example>
</service>
<service name="varnish">
<example>
services.varnish = {
enable = true;
vcl = ''
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
'';
};
</example>
</service>
services.mailhog.enable = true;
<service name="mailpit">
<example>
services.mailpit.enable = true;
</example>
</service>
<decision_tree name="service_selection">
What type of storage/service do you need?
Use postgres or mysql
Use mongodb
Use redis or memcached
Use minio
Use elasticsearch or opensearch
Use rabbitmq or kafka
Use nginx or caddy
Use mailhog or mailpit
</decision_tree>
Pre-commit hooks via git-hooks.hooks
git-hooks.hooks = {
# Formatters
nixfmt-rfc-style.enable = true;
prettier.enable = true;
black.enable = true;
rustfmt.enable = true;
# Linters
eslint.enable = true;
clippy.enable = true;
shellcheck.enable = true;
# Security
detect-private-keys.enable = true;
check-merge-conflicts.enable = true;
# Git hygiene
check-case-conflicts.enable = true;
editorconfig-checker.enable = true;
};
</example>
<custom_hook>
git-hooks.hooks.my-custom-hook = {
enable = true;
name = "my-custom-hook";
entry = "${pkgs.bash}/bin/bash -c 'echo Running custom hook'";
files = "\\.nix$";
pass_filenames = true;
};
</custom_hook>
<common_hooks>
<hook name="nixfmt-rfc-style">Nix code formatter (RFC style)</hook>
<hook name="prettier">JavaScript/TypeScript/CSS/HTML formatter</hook>
<hook name="black">Python code formatter</hook>
<hook name="rustfmt">Rust code formatter</hook>
<hook name="ormolu">Haskell code formatter</hook>
<hook name="gofmt">Go code formatter</hook>
<hook name="eslint">JavaScript/TypeScript linter</hook>
<hook name="clippy">Rust linter</hook>
<hook name="shellcheck">Shell script linter</hook>
<hook name="yamllint">YAML linter</hook>
<hook name="actionlint">GitHub Actions linter</hook>
<hook name="hadolint">Dockerfile linter</hook>
<hook name="markdownlint">Markdown linter</hook>
<hook name="detect-private-keys">Prevent committing private keys</hook>
<hook name="check-merge-conflicts">Prevent committing merge conflicts</hook>
<hook name="check-case-conflicts">Detect case conflicts in filenames</hook>
<hook name="editorconfig-checker">Check editorconfig compliance</hook>
<hook name="treefmt">Universal formatter via treefmt</hook>
</common_hooks>
Custom scripts available in devenv shell
scripts = {
build.exec = "cargo build --release";
test.exec = "cargo test";
lint.exec = "cargo clippy -- -D warnings";
fmt.exec = "cargo fmt";
dev.exec = "cargo watch -x run";
# With description
deploy = {
exec = "kubectl apply -f k8s/";
description = "Deploy to Kubernetes";
};
# Using packages
migrate = {
exec = "${pkgs.dbmate}/bin/dbmate up";
description = "Run database migrations";
};
};
</example>
Background processes managed by native process manager (devenv 2.0 default) or process-compose
In devenv 2.0, the native process manager is the default. To use process-compose instead, set process.manager.implementation = "process-compose".
processes = {
web.exec = "npm run dev";
api.exec = "cargo run";
worker.exec = "python worker.py";
};
<process_compose_example>
# To use process-compose (no longer the default in 2.0):
process.manager.implementation = "process-compose";
processes = {
web = {
exec = "npm run dev";
process-compose = {
depends_on.api.condition = "process_healthy";
readiness_probe = {
http_get = {
host = "localhost";
port = 3000;
};
};
};
};
api = {
exec = "cargo run";
process-compose = {
readiness_probe = {
http_get = {
host = "localhost";
port = 8080;
path = "/health";
};
};
};
};
};
</process_compose_example>
Named tasks with dependencies (devenv 1.7+)
tasks = {
"build:frontend" = {
exec = "npm run build";
before = [ "devenv:enterShell" ];
};
"build:backend" = {
exec = "cargo build --release";
before = [ "devenv:enterShell" ];
};
"build:all" = {
exec = "echo Build complete";
after = [ "build:frontend" "build:backend" ];
};
};
Environment variables
env = {
DATABASE_URL = "postgres://localhost/myapp";
REDIS_URL = "redis://localhost:6379";
SECRET_KEY = "development-secret";
DEBUG = "true";
};
<dotenv_example>
dotenv.enable = true;
dotenv.filename = ".env.local";
</dotenv_example>
Commands to run when entering shell
enterShell = ''
echo "Welcome to the development environment!"
export PS1="(devenv) $PS1"
'';
Commands to run in test environment
enterTest = ''
echo "Running tests..."
cargo test
'';
Build outputs and packaging (devenv 1.6+)
Package applications using language-specific builders
{ config, ... }:
{
languages.rust.enable = true;
languages.python.enable = true;
languages.go.enable = true;
outputs = {
rust-app = config.languages.rust.import ./rust-app {};
python-app = config.languages.python.import ./python-app {};
go-app = config.languages.go.import ./go-app {};
};
}
</example>
Multiple shell configurations via devenv.shells (devenv 2.0+)
# devenv.nix
{ pkgs, ... }:
{
devenv.shells.default = {
languages.python.enable = true;
packages = [ pkgs.git ];
};
devenv.shells.ci = {
languages.python.enable = true;
packages = [ pkgs.git pkgs.buildkit ];
env.CI = "true";
};
devenv.shells.docs = {
packages = [ pkgs.mdbook ];
scripts.build-docs.exec = "mdbook build";
};
}
</example>
Custom flake outputs via devenv.outputs (devenv 2.0+)
{ pkgs, config, ... }:
{
devenv.outputs = {
packages.my-app = config.languages.rust.import ./. {};
checks.lint = pkgs.runCommand "lint" {} ''
${pkgs.clippy}/bin/cargo-clippy
touch $out
'';
};
}
Custom derivation as output
{ pkgs, ... }:
{
outputs.my-app = pkgs.stdenv.mkDerivation {
pname = "my-app";
version = "1.0.0";
src = ./.;
buildPhase = "make";
installPhase = "make install PREFIX=$out";
};
}
Configuration profiles for different contexts (devenv 1.9+)
Define profile-specific configuration
{ pkgs, ... }:
{
languages.python.enable = true;
languages.python.version = "3.13";
profiles = {
"python-3.12".config = {
languages.python.version = "3.12";
};
"python-3.11".config = {
languages.python.version = "3.11";
};
};
}
</example>
<usage>devenv shell --profile python-3.12</usage>
Profiles based on team roles
{ pkgs, ... }:
{
languages.nix.enable = true;
profiles = {
backend.module = {
languages.rust.enable = true;
services.postgres.enable = true;
services.redis.enable = true;
};
frontend.module = {
languages.javascript.enable = true;
languages.typescript.enable = true;
};
fullstack.extends = [ "backend" "frontend" ];
};
}
</example>
Automatic profiles based on hostname or user
{ pkgs, ... }:
{
profiles = {
hostname."ci-server".module = {
env.CI = "true";
packages = [ pkgs.buildkit ];
};
user."developer".module = {
packages = [ pkgs.gh ];
};
};
}
</example>
Minimal devenv.nix for quick setup
{ pkgs, ... }:
{
packages = [ pkgs.git ];
languages.python.enable = true;
}
Full-stack web development setup
{ pkgs, config, ... }:
{
packages = [ pkgs.git pkgs.curl pkgs.jq ];
languages = {
javascript = {
enable = true;
package = pkgs.nodejs_24;
pnpm.enable = true;
};
typescript.enable = true;
};
services = {
postgres = {
enable = true;
initialDatabases = [{ name = "app_dev"; }];
};
redis.enable = true;
};
processes = {
frontend.exec = "pnpm dev";
api.exec = "pnpm api:dev";
};
scripts = {
db-migrate.exec = "pnpm db:migrate";
db-seed.exec = "pnpm db:seed";
};
git-hooks.hooks = {
prettier.enable = true;
eslint.enable = true;
};
}
</example>
Nix development project
{ pkgs, ... }:
{
languages.nix = {
enable = true;
lsp.package = pkgs.nixd;
};
packages = [ pkgs.nixfmt-rfc-style ];
git-hooks.hooks = {
nixfmt-rfc-style.enable = true;
editorconfig-checker.enable = true;
};
}
</example>
MCP server integration (devenv 1.7+)
{ pkgs, inputs, ... }:
let
mcp-servers = inputs.mcp-servers-nix.lib.evalModule pkgs {
programs.nixos.enable = true;
};
in {
files.".mcp.json".json = {
mcpServers = mcp-servers.config.settings.servers;
};
}
<decision_tree name="configuration_approach">
What type of project are you setting up?
Use minimal_config pattern
Use full_stack pattern
Use nix_project pattern
Use profiles with team modules
</decision_tree>
<context7_integration>
<library_id>/cachix/devenv</library_id>
<trust_score>9.7</trust_score>
1354
<usage_patterns>
Fetch specific language configuration options
Fetch service configuration details
Fetch available pre-commit hooks
Fetch packaging patterns
Fetch profile configuration (1.9+)
Fetch devenv 2.0 features and migration guide
</usage_patterns>
</context7_integration>
<best_practices>
Use languages.*.enable instead of adding language packages directly to packages list
Keep enterShell fast; move slow operations to tasks or scripts
Use git-hooks for consistent code quality across team
Use services.* instead of running databases manually
Use dotenv.enable for environment-specific configuration
In devenv 2.0, prefer the native process manager (default). Only switch to process-compose if you need advanced features like health checks and dependency ordering.
Document scripts with description attribute
Use profiles for multi-context development (different language versions, team roles)
Use outputs for packaging applications when needed
<anti_patterns>
Hardcoding specific package versions instead of using version options
Use languages..version or languages..package with nixpkgs packages
Using shell commands to install packages instead of using packages attribute
Use packages = [ pkgs.package-name ]; for declarative package management
Using network-dependent commands in enterShell
Use tasks or scripts for network operations; keep enterShell fast and offline-capable
Running slow operations in enterShell
Use tasks with explicit triggers instead of always running in enterShell
Enabling multiple conflicting package managers (npm and pnpm and yarn)
Choose one package manager per project (npm OR pnpm OR yarn OR bun)
Storing production secrets in env attribute
Use dotenv.enable with .env files in .gitignore, or use external secret management
Assuming process-compose is the default process manager in devenv 2.0
Native process manager is the default in devenv 2.0. Set process.manager.implementation = "process-compose" explicitly if needed.
Using manual shell hooks (e.g. shellHook, .bashrc modifications) instead of enterShell
Use enterShell for shell initialization. Use scripts for reusable commands. Use tasks for build-time operations.
Hardcoding absolute paths instead of using devenv variables (config.devenv.root, config.env.DEVENV_STATE, config.env.DEVENV_DOTFILE)
Use config.devenv.root for project root, config.env.DEVENV_STATE for state directory, and config.env.DEVENV_DOTFILE for the .devenv directory path.
Using process-compose directly (e.g. adding process-compose.yaml or running process-compose commands) instead of devenv processes
Use processes.* with the native process manager (devenv 2.0 default). For advanced features, set process.manager.implementation = "process-compose" and configure via process-compose attribute on each process.
Use devenv languages.* options instead of manually adding language packages
Use devenv services.* instead of manual service setup
Keep enterShell lightweight and fast
In devenv 2.0, native process manager is the default; set process.manager.implementation = "process-compose" explicitly for process-compose
Enable git-hooks for code quality enforcement
Use scripts for common development commands
Document configuration with comments
Use profiles for environment variations
Understand devenv configuration requirements
1. Identify required languages and their versions
Workflow guidance
Step completed
2. Determine needed services (databases, caches, etc.)
Workflow guidance
Step completed
3. Plan background processes and scripts
Workflow guidance
Step completed
4. Consider team profiles if multi-developer project
Workflow guidance
Step completed
Write devenv.nix configuration
1. Start with minimal configuration (packages, primary language)
Workflow guidance
Step completed
2. Add services with appropriate settings
Workflow guidance
Step completed
3. Configure git-hooks for code quality
Workflow guidance
Step completed
4. Add scripts for common operations
Workflow guidance
Step completed
5. Set up processes for development servers (native process manager is default in 2.0)
Workflow guidance
Step completed
6. Add profiles if needed
Workflow guidance
Step completed
Verify devenv configuration works
1. Run devenv shell to verify environment
Workflow guidance
Step completed
2. Run devenv up to verify processes start
Workflow guidance
Step completed
3. Test git hooks with sample commits
Workflow guidance
Step completed
4. Verify scripts work as expected
Workflow guidance
Step completed
<error_escalation>
Missing optional configuration attribute
Note in output, suggest improvement
Service configuration incomplete or enterShell too slow
Document issue, suggest refactoring approach
Configuration fails to evaluate or services fail to start
Debug with devenv info, present options to user
Security issue in configuration (secrets exposed, unsafe permissions)
Block operation, require explicit user acknowledgment
</error_escalation>
Use devenv languages.* options for language configuration
Use devenv services.* for service management
Follow project existing devenv patterns if present
Be aware that native process manager is the default in devenv 2.0
Hardcoding versions instead of using version options
Slow operations in enterShell
Mixing multiple conflicting package managers
Storing secrets in env attribute
Assuming process-compose is still the default process manager
<related_skills>
Nix language fundamentals, flakes, Home Manager (devenv uses Nix)
Symbol operations for navigating devenv configurations
Fetch latest devenv documentation
</related_skills>