Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cachix/devenv/llms.txt

Use this file to discover all available pages before exploring further.

The devenv.nix file is the heart of every devenv project. It is a Nix module that accepts a set of structured options to declare your developer environment — packages, environment variables, language toolchains, services, processes, tasks, scripts, containers, and more. This page documents every top-level option group available in devenv.nix.
This reference covers the most important option groups. The complete machine-generated list (49,000+ lines) lives in the devenv source repository.

packages

A list of packages to expose inside the developer environment. Search available packages with devenv search NAME.
FieldValue
Typelist of package
Default[]
packages = [ pkgs.git pkgs.ripgrep pkgs.curl ];

env

Environment variables to be exposed inside the developer environment. Accepts any attribute set — values can be strings, numbers, or booleans.
FieldValue
Typeopen submodule of lazy attribute set of anything
Default{}
env = {
  GREET = "hello";
  DATABASE_URL = "postgres://localhost:5432/mydb";
  DEBUG = "true";
};

enterShell

Bash code to execute when entering the developer shell (via devenv shell). Runs after all language and service hooks.
FieldValue
Typestrings concatenated with "\n"
Default""
enterShell = ''
  echo "Welcome to the dev environment!"
  git --version
  hello  # run a script
'';

enterTest

Bash code to execute when running tests via devenv test. Runs inside the environment after processes have started.
FieldValue
Typestrings concatenated with "\n"
Default""
enterTest = ''
  echo "Running tests"
  git --version | grep "${pkgs.git.version}"
  wait_for_port 5432  # wait for postgres
  pytest tests/
'';

overlays

A list of nixpkgs overlays to apply. Each overlay is a function (final: prev: { ... }). Requires devenv 1.4.2+.
FieldValue
Typelist of function
Default[]
overlays = [
  (final: prev: {
    hello = prev.hello.overrideAttrs (old: {
      patches = (old.patches or []) ++ [ ./hello-fix.patch ];
    });
  })
];

unsetEnvVars

A list of environment variable names to unset when entering the shell. Useful for removing variables set by parent shells that would interfere with the environment.
FieldValue
Typelist of string
Default[]

scripts.<name>.*

Named shell scripts that become available as commands in the developer environment. Scripts are placed on $PATH and can reference all packages in the environment.
scripts.<name>.exec
string or absolute path
required
Shell code to execute when the script is run, or an absolute path to a script file.
scripts.<name>.description
string
default:"\"\""
Human-readable description of the script.
scripts.<name>.package
package
default:"pkgs.bash"
The shell package used to run the script.
scripts.<name>.packages
list of package
default:"[]"
Extra packages to add to PATH when the script runs.
scripts.<name>.binary
null or string
default:"null"
Override the binary name derived from package.meta.mainProgram.
scripts = {
  hello.exec = ''echo "Hello from $GREET"'';
  hello.description = "Print a greeting";

  db-reset = {
    exec = ''
      psql "$DATABASE_URL" -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
    '';
    description = "Reset the database schema";
    packages = [ pkgs.postgresql ];
  };
};

tasks.<name>.*

Declarative tasks with DAG-based dependency ordering, caching, and parallel execution. Tasks run via devenv tasks run <name> or automatically on shell entry when listed in devenv:enterShell.
tasks.<name>.exec
null or string
default:"null"
Command to execute the task.
tasks.<name>.description
string
default:"\"\""
Human-readable description of the task.
tasks.<name>.after
list of string
default:"[]"
Tasks that must complete before this task runs. Supports suffixes: @started, @succeeded (default), @completed.
tasks.<name>.before
list of string
default:"[]"
Tasks that should run after this task completes. The inverse of after.
tasks.<name>.binary
null or string
default:"null"
Override the binary name from package.meta.mainProgram.
tasks.<name>.cwd
null or string
default:"null"
Working directory to run the task in. Defaults to the project root.
tasks.<name>.env
attribute set of string
default:"{}"
Environment variables to set for this task only.
tasks.<name>.execIfModified
list of string
default:"[]"
Paths to files that trigger task execution if modified (enables caching).
tasks.<name>.exports
list of string
default:"[]"
Environment variable names this task exports to downstream tasks.
tasks.<name>.input
attribute set of anything
default:"{}"
Input values for the task, encoded as JSON.
tasks.<name>.package
package
default:"pkgs.bash"
Package to install for this task.
tasks.<name>.showOutput
boolean
default:"false"
Always show task output (stdout and stderr), regardless of success or failure.
tasks.<name>.status
null or string
default:"null"
Shell command to check whether the task should run. Exit code 0 means skip, non-zero means run.
tasks.<name>.type
one of "oneshot", "process"
default:"\"oneshot\""
Task type: oneshot runs once and completes; process is a long-running service.
tasks = {
  "myapp:setup".exec = "mytool build";
  "myapp:db-migrate" = {
    exec = "alembic upgrade head";
    after = [ "devenv:enterShell" ];
    execIfModified = [ "migrations/" ];
  };
  "devenv:enterShell".after = [ "myapp:setup" ];
};
Task dependency suffixes control when the dependency is considered satisfied:
  • task@started — wait for execution to begin
  • task@succeeded (default for tasks) — wait for successful completion
  • task@ready (default for processes) — wait for the process readiness probe
  • task@completed — wait for finish regardless of exit code (soft dependency)

processes.<name>.*

Long-running background processes managed by devenv’s native Rust process manager. Start all processes with devenv up.
processes.<name>.exec
string
required
Bash code to run the process.
processes.<name>.after
list of string
default:"[]"
Tasks/processes that must be ready before this process starts.
processes.<name>.before
list of string
default:"[]"
Tasks/processes that should start after this process is ready.
processes.<name>.cwd
null or string
default:"null"
Working directory for the process. Defaults to the current working directory.
processes.<name>.env
attribute set of string
default:"{}"
Environment variables to set for this process only.
processes.<name>.linux.capabilities
list of string
default:"[]"
Linux ambient capabilities to add (e.g. "cap_net_admin"). Requires devenv 2.0+.
processes.<name>.listen
list of (submodule)
default:"[]"
Socket activation configuration for systemd-style socket passing. Requires devenv 2.0+.
processes.<name>.ports.<name>.allocate
integer
Base port for auto-allocation. devenv increments from this value until a free port is found.
processes.<name>.ports.<name>.value
integer (read-only)
The resolved port value after auto-allocation. Read this in exec as config.processes.&lt;name&gt;.ports.&lt;port&gt;.value.
processes.<name>.ready
submodule
Readiness probe configuration. Supports exec, http.get, and systemd notify modes.
processes.<name>.restart.on
one of "always", "on_failure", "never"
default:"\"on_failure\""
When to restart the process: "on_failure" (default) restarts only on non-zero exit, "always" restarts on any exit, "never" never restarts.
processes.<name>.restart.max
integer
Maximum number of restarts before giving up.
processes.<name>.restart.window
integer
Time window in seconds for counting restart attempts.
processes.<name>.watch.paths
list of string
default:"[]"
Paths to watch for file changes; the process restarts when changes are detected.
processes.<name>.watch.extensions
list of string
default:"[]"
File extensions to watch (e.g. [".rs" ".toml"]).
processes.<name>.watch.ignore
list of string
default:"[]"
Glob patterns for paths to ignore when watching.
processes.<name>.watchdog.usec
integer
Watchdog interval in microseconds. The process must notify the watchdog within this interval.
processes.<name>.start.enable
boolean
default:"true"
Whether this process should start automatically with devenv up.
processes = {
  server = {
    exec = "uvicorn myapp:app --reload --port 8000";
    ready.http.get = {
      host = "localhost";
      path = "/health";
      port = 8000;
      scheme = "http";
    };
  };
  worker = {
    exec = "celery -A myapp worker";
    after = [ "devenv:processes:postgres@ready" ];
    restart.on = "on_failure";
    restart.max = 5;
  };
};

languages.<name>.*

devenv ships with 50+ language modules. Each language follows a common pattern — enable it, optionally pin a version or package, and configure tooling. Below are the most commonly used languages; every language also supports a .lsp sub-option to enable the bundled language server.

Common language options pattern

OptionTypeDescription
languages.<lang>.enablebooleanWhether to enable this language toolchain
languages.<lang>.packagepackageOverride the compiler/runtime package
languages.<lang>.versionstringPin a specific version (where supported)
languages.<lang>.lsp.enablebooleanEnable the bundled LSP server
languages.<lang>.lsp.packagepackageOverride the LSP package

languages.rust.*

languages.rust.enable
boolean
default:"false"
Enable the Rust toolchain.
languages.rust.channel
string
default:"\"stable\""
Rust release channel: "stable", "beta", or "nightly".
languages.rust.components
list of string
Rust components to install (e.g. ["rustfmt" "clippy"]).
languages.rust.targets
list of string
default:"[]"
Cross-compilation targets to add (e.g. ["wasm32-unknown-unknown"]).
languages.rust.toolchain
submodule
Fine-grained toolchain overrides: rustc, cargo, clippy, rustfmt, rust-analyzer.
languages.rust.toolchainFile
null or path
default:"null"
Path to a rust-toolchain.toml file to derive the toolchain from.
languages.rust.mold.enable
boolean
default:"false"
Use the mold linker for faster builds (Linux only).
languages.rust.cranelift.enable
boolean
default:"false"
Use the Cranelift codegen backend for faster debug builds.
languages.rust.import
function
Import function for packaging Rust applications via crate2nix. Use in outputs.

languages.python.*

languages.python.enable
boolean
default:"false"
Enable Python.
languages.python.package
package
default:"pkgs.python3"
Python interpreter package.
languages.python.directory
string
default:"\".\""
Directory containing the Python project (for virtualenv placement).
languages.python.poetry.enable
boolean
default:"false"
Enable Poetry package manager.
languages.python.poetry.install.enable
boolean
default:"false"
Run poetry install automatically on shell entry.
languages.python.poetry.activate.enable
boolean
default:"false"
Activate the Poetry virtualenv automatically.
languages.python.manylinux.enable
boolean
default:"false"
Enable manylinux compatibility for binary wheels.
languages.python.import
function
Import function for packaging Python applications via uv2nix. Use in outputs.

languages.javascript.*

languages.javascript.enable
boolean
default:"false"
Enable Node.js/JavaScript tooling.
languages.javascript.package
package
Node.js package to use.
languages.javascript.bun.enable
boolean
default:"false"
Enable Bun runtime.
languages.javascript.bun.install.enable
boolean
default:"false"
Run bun install automatically on shell entry.
languages.javascript.corepack.enable
boolean
default:"false"
Enable corepack for package manager management.
languages.javascript.directory
string
Directory containing package.json.

languages.go.*

languages.go.enable
boolean
default:"false"
Enable Go.
languages.go.package
package
Go compiler package.
languages.go.version
string
Pin a specific Go version.
languages.go.delve.enable
boolean
default:"false"
Enable the Delve debugger.

Other supported languages

LanguageModuleNotes
Androidlanguages.androidSDK, ABIs, build tools, emulator
C / C++languages.c, languages.cplusplusClang/GCC, clangd LSP
Clojurelanguages.clojureclj-kondo LSP
Crystallanguages.crystalshards support
Cuelanguages.cue
Dart / Flutterlanguages.dart
Denolanguages.deno
.NETlanguages.dotnet
Elixirlanguages.elixir
Elmlanguages.elm
Erlanglanguages.erlang
Fortranlanguages.fortran
Gleamlanguages.gleam
Haskelllanguages.haskellcabal, stack, HLS
Helmlanguages.helm
Idrislanguages.idris
Javalanguages.javaGradle, Maven, multiple JDKs
PHPlanguages.phpFPM pools, extensions
Rubylanguages.ruby
Scalalanguages.scala
Swiftlanguages.swift
Terraformlanguages.terraform
TypeScriptlanguages.typescript
Ziglanguages.zig

services.<name>.*

devenv supports 40+ pre-configured services that start with devenv up. Services share common options (enable, package, port) and provide service-specific configuration.

Common service options pattern

OptionTypeDescription
services.<svc>.enablebooleanWhether to enable the service
services.<svc>.packagepackageOverride the service package
services.<svc>.portintegerPort to listen on

services.postgres.*

services.postgres.enable
boolean
default:"false"
Enable PostgreSQL.
services.postgres.package
package
default:"pkgs.postgresql"
PostgreSQL package (e.g. pkgs.postgresql_16).
services.postgres.port
integer
default:"5432"
TCP port to accept connections on.
services.postgres.createDatabase
boolean
default:"true"
Create a database named after the current user on first start.
services.postgres.extensions
list of function
default:"[]"
PostgreSQL extensions to enable (e.g. extensions: [ extensions.postgis ]).
services.postgres.initialDatabases
list of submodule
default:"[]"
List of databases to create on first start, each with name, user, pass, schema, initialSQL.
services.postgres.initialScript
null or string
default:"null"
SQL script to run on first initialization.
services.postgres.settings
attribute set
default:"{}"
postgresql.conf settings as a Nix attribute set.
services.postgres.listen_addresses
string
default:"\"127.0.0.1\""
Addresses to listen on.
services.postgres.hbaConf
string
Full content of pg_hba.conf.
services.postgres.initdbArgs
list of string
default:"[\"--no-locale\" \"--encoding=UTF8\"]"
Extra arguments to pass to initdb.

services.redis.*

services.redis.enable
boolean
default:"false"
Enable Redis.
services.redis.port
integer
default:"6379"
Port to listen on.
services.redis.bind
string
default:"\"127.0.0.1\""
Address to bind to.
services.redis.extraConfig
string
default:"\"\""
Additional lines for redis.conf.

services.mysql.*

services.mysql.enable
boolean
default:"false"
Enable MySQL/MariaDB.
services.mysql.initialDatabases
list of submodule
default:"[]"
Databases to create on first start, each with name and optional schema.
services.mysql.ensureUsers
list of submodule
default:"[]"
Users to create with name, password, host, and ensurePermissions.

services.elasticsearch.*

services.elasticsearch.enable
boolean
default:"false"
Enable Elasticsearch.
services.elasticsearch.port
integer
default:"9200"
HTTP port.
services.elasticsearch.single_node
boolean
default:"true"
Enable single-node discovery mode.

services.mongodb.*

services.mongodb.enable
boolean
default:"false"
Enable MongoDB.
services.mongodb.replication.enable
boolean
default:"false"
Enable replication.

services.nginx.*

services.nginx.enable
boolean
default:"false"
Enable nginx web server.
services.nginx.httpConfig
string
Raw nginx http {} block configuration.
services.nginx.virtualHosts
attribute set of submodule
default:"{}"
Virtual host definitions, each with extraConfig and serverAliases.

Other supported services

ServiceModule
Adminerservices.adminer
Blackfireservices.blackfire
Caddyservices.caddy
Cassandraservices.cassandra
ClickHouseservices.clickhouse
CockroachDBservices.cockroachdb
DynamoDB Localservices.dynamodb-local
EventStoreDBservices.eventstore
Grafanaservices.grafana
Kafkaservices.kafka
Keycloakservices.keycloak
Mailhogservices.mailhog
MariaDBservices.mysql (with MariaDB package)
Meilisearchservices.meilisearch
MinIOservices.minio
OpenSearchservices.opensearch
Prometheusservices.prometheus
RabbitMQservices.rabbitmq
Surrealdbservices.surrealdb
Temporalservices.temporal
Vaultservices.vault
Wiremockservices.wiremock
Zookeeperservices.zookeeper

containers.<name>.*

OCI container specifications for building, copying, and running containers without Docker.
containers.<name>.startupCommand
null or string or package or list of string
default:"null"
Command to run in the container. Can be a string, package, or list of arguments.
containers.<name>.name
null or string
Container image name. Defaults to the attribute name.
containers.<name>.version
null or string
default:"\"latest\""
Container image tag.
containers.<name>.registry
null or string
default:"\"docker-daemon:\""
Registry to push the container to.
containers.<name>.copyToRoot
absolute path or list of absolute path
default:"self"
Path(s) to add to the container root. Defaults to the entire project.
containers.<name>.fromImage
null or package
default:"null"
Base OCI image to build on top of (built with nix2container.pullImage).
containers.<name>.entrypoint
list of anything
Container entrypoint command.
containers.<name>.workingDir
string
default:"\"/env\""
Working directory inside the container.
containers.<name>.enableLayerDeduplication
boolean
default:"true"
Use content-addressed layer deduplication to minimize image size.
containers.<name>.maxLayers
integer
Maximum number of layers in the container image.
containers.<name>.defaultCopyArgs
list of string
default:"[]"
Default arguments to pass to skopeo copy.
containers.<name>.isBuilding
boolean
default:"false"
Set to true inside the container build context. Useful for conditional configuration.
containers.app = {
  name = "myapp";
  version = "1.0.0";
  startupCommand = config.processes.server.exec;
  registry = "ghcr.io/myorg/";
};

outputs.*

Arbitrary Nix outputs exposed for devenv build consumption. Can be any Nix value — packages, derivations, or nested attribute sets.
FieldValue
TypeoutputOf (attribute set)
Default{}
outputs = {
  git = pkgs.git;
  # Language-specific app packaging:
  rust-app = config.languages.rust.import ./rust-app {};
  python-app = config.languages.python.import ./python-app {};
};

profiles.<name>.*

Profile definitions for environment variants. Activate with --profile <name> or set a default in devenv.yaml.
profiles.<name>.module
module
default:"{}"
Additional Nix module configuration to merge when this profile is active.
profiles.<name>.extends
list of string
default:"[]"
List of profile names to inherit from.
profiles.hostname.<hostname>.*
Profiles automatically activated when the machine’s hostname matches. Same sub-options as profiles.<name>.
profiles.user.<username>.*
Profiles automatically activated when the current user matches. Same sub-options as profiles.<name>.
profiles = {
  base.module = {
    languages.nix.enable = true;
    packages = [ pkgs.git ];
  };
  backend = {
    extends = [ "base" ];
    module = {
      services.postgres.enable = true;
      services.redis.enable = true;
    };
  };
  hostname."work-laptop" = {
    extends = [ "backend" ];
    module.env.WORK = "true";
  };
};

files.<name>.*

Files to create and link into the devenv project root. Useful for seeding config files or generating structured configuration from Nix.
files.<name>.text
null or string
default:"null"
Raw text content of the file.
files.<name>.json
null or JSON value
default:"null"
JSON content — automatically serialized.
files.<name>.toml
null or TOML value
default:"null"
TOML content — automatically serialized.
files.<name>.yaml
null or YAML 1.1 value
default:"null"
YAML content — automatically serialized.
files.<name>.ini
null or INI attribute set
default:"null"
INI content — automatically serialized.
files.<name>.source
null or absolute path
default:"null"
An absolute path to a source file to copy or link.
files.<name>.executable
boolean
default:"false"
Make the file executable.
files.<name>.copyMode
one of "symlink", "seed", "copy"
default:"\"symlink\""
How to materialize the file:
  • symlink — symlink to the Nix store (read-only, always up to date)
  • seed — copy once if the file doesn’t exist yet (editable)
  • copy — overwrite with fresh contents on every shell entry
files = {
  ".editorconfig".text = ''
    root = true
    [*]
    indent_style = space
    indent_size = 2
  '';
  "config/settings.json".json = {
    debug = false;
    logLevel = "info";
  };
};

git-hooks.*

Integration with git-hooks.nix for managing git pre-commit hooks.
git-hooks.enable
boolean
default:"false"
Whether to enable the git-hooks pre-commit module globally.
git-hooks.default_stages
list of string
default:"[\"pre-commit\"]"
Default stages for hooks that don’t specify their own.
git-hooks.excludes
list of string
default:"[]"
Global list of regex patterns for files to exclude from all hooks.

git-hooks.hooks.<name>.*

git-hooks.hooks.<name>.enable
boolean
default:"false"
Enable this pre-commit hook. Many well-known hooks are pre-defined; just set .enable = true.
git-hooks.hooks.<name>.package
null or package
default:"null"
Package providing the hook binary.
git-hooks.hooks.<name>.entry
string
The command entry point for the hook.
git-hooks.hooks.<name>.args
list of string
default:"[]"
Additional arguments to pass to the hook command.
git-hooks.hooks.<name>.files
string
default:"\"\""
Regex pattern for files this hook applies to.
git-hooks.hooks.<name>.types
list of string
default:"[\"file\"]"
File types this hook applies to.
git-hooks.hooks.<name>.language
string
default:"\"system\""
Language environment for running the hook.
git-hooks.hooks.<name>.stages
list of string
Git stages this hook runs on (e.g. ["pre-commit" "pre-push"]).
git-hooks.hooks.<name>.pass_filenames
boolean
default:"true"
Pass staged filenames as arguments to the hook.
git-hooks.hooks.<name>.always_run
boolean
default:"false"
Run the hook even if no files match.
git-hooks.hooks.<name>.fail_fast
boolean
default:"false"
Stop running hooks after the first failure.
git-hooks.hooks.<name>.priority
integer
default:"0"
Hook execution priority (lower runs first).
git-hooks.hooks.<name>.before
list of string
default:"[]"
List of hooks that must run after this hook.
git-hooks.hooks.<name>.after
list of string
default:"[]"
List of hooks that must run before this hook.
git-hooks.hooks.<name>.extraPackages
list of package
default:"[]"
Extra packages to add to PATH when the hook runs.
git-hooks.hooks = {
  shellcheck.enable = true;
  nixfmt-rfc-style.enable = true;
  clippy.enable = true;
  # Custom hook:
  my-linter = {
    enable = true;
    entry = "${pkgs.my-linter}/bin/lint";
    files = "\\.py$";
    types = [ "python" ];
  };
};
Many formatters and linters are available as named hooks: alejandra, autoflake, biome, black, clippy, nixfmt, prettier, ruff-check, ruff-format, rustfmt, shellcheck, shfmt, stylua, and many more.

Additional top-level options

OptionTypeDefaultDescription
certFilenull or absolute pathnullPath to a CA certificate file to trust
certificateslist of string[]List of domain names to generate self-signed certificates for
cachix.enablebooleanfalseEnable Cachix integration
cachix.pushnull or stringnullCachix cache name to push to
cachix.pulllist of string[]Cachix caches to pull from
delta.enablebooleanfalseIntegrate delta as the git pager
devcontainer.enablebooleanfalseGenerate .devcontainer.json for VS Code devcontainer support
difftastic.enablebooleanfalseIntegrate difftastic as the git diff tool
git.rootnull or stringnullGit repository root (auto-populated in devenv 1.10+)
secretspec.enableboolean (read-only)falseWhether secretspec integration is active
secretspec.providernull or string (read-only)nullSecretspec provider used to load secrets
secretspec.profilenull or string (read-only)nullSecretspec profile used to load secrets
treefmt.enablebooleanfalseEnable treefmt formatter integration
process.manager.implementationstring"process-compose"Process manager to use with devenv up
container.isBuildingbooleanfalsetrue when building any container
apple.sdkpackageApple SDK to use on macOS
claude.code.enablebooleanfalseConfigure Claude Code AI assistant

Build docs developers (and LLMs) love