Fast, Declarative, Reproducible and Composable Developer Environments using Nix

Develop nativelyDeploy containers100,000+ packagesWrite scripts and tasks50+ languagesDefine processesReuse servicesRun testsEnforce git hooks

Simple JSON-like language

Declaratively define your development environment by toggling basic options.

Environment variables
Use env attribute set to define environment variables.

Include secrets from .env file with dotenv.enable = true;.

Packages
Pick from 100,000+ prebuilt packages for Linux/macOS and x64/ARM64. Works with WSL2.
Shell initialization
Run scripts when entering the environment with enterShell.
Automatic activation
Using direnv will automatically load the environment when you enter the project directory.
devenv.nix
{ pkgs, config, ... }: {
  env.GREET = "determinism";

  packages = [
    pkgs.ncdu
  ];

  enterShell = ''
    echo hello ${config.env.GREET}
    ncdu --version
  '';
}
devenv shell
hello determinism
ncdu 2.3

devenv.nix
{ pkgs, ... }: {
  packages = [ pkgs.yarn ];

  scripts.build.exec = "yarn build";

  tasks."myapp:build" = {
    exec = "build";
    before = [ "devenv:enterShell" ];
  };

  # Runs on `git commit` and `devenv test`
  git-hooks.hooks = {
    black.enable = true;
    # Your custom hooks
    generate-css = {
      enable = true;
      name = "generate-css";
      entry = "build";
    };
  };
}
devenv shell
...
Running tasks     devenv:enterShell
Succeeded         devenv:git-hooks:install 15ms
Succeeded         myapp:build               23ms
Succeeded         devenv:enterShell         23ms
3 Succeeded                                 50.14ms
$

Scripts and Tasks

Define scripts, tasks, and git hooks to automate your development workflow.

Scripts
Define scripts that can be invoked inside the environment, using all the packages and environment variables.
Tasks
Form dependencies between automation code, executed in parallel and written in your favorite language.
Git hooks
Pick from builtin and language-specific linters and formatters using git-hooks.nix.

Search packages and options

Explore packages and options to customize your environment.

devenv search devenv
+--------------+---------------+------------------------------------------------------------------------+
| Package      | Version       | Description                                                            |
+--------------+---------------+------------------------------------------------------------------------+
| pkgs.devenv  | 1.0.3         | Fast, Declarative, Reproducible, and Composable Developer Environments |
+--------------+---------------+------------------------------------------------------------------------+
+--------------------------+---------+-----------+------------------------------------------------------------+
| Option                   | Type    | Default   | Description                                                |
+--------------------------+---------+-----------+------------------------------------------------------------+
| devenv.debug             | boolean | false     | Whether to enable debug mode of devenv enterShell script.  |
+--------------------------+---------+-----------+------------------------------------------------------------+
| devenv.warnOnNewVersion  | boolean | true      | Whether to warn when a new version of devenv is available. |
+--------------------------+---------+-----------+------------------------------------------------------------+
| devenv.latestVersion     | string  | "1.0.3"   | The latest version of devenv.                              |
+--------------------------+---------+-----------+------------------------------------------------------------+
• Found 1 package and 3 options for 'devenv'.

Languages

Supports over 50 programming languages.

Packed with tooling
Comes with commonly used tooling for each language including LSP servers, formatters, linters, and compilers.
Version support
Languages like Python, Terraform, Rust, PHP, and Ruby all have version support.
Examples
Check out the examples collection to get started.
devenv.nix
{ pkgs, config, ... }: {
  languages.python = {
    enable = true;
    version = "3.11";
    venv.enable = true;
    venv.requirements = ''
      requests
      torch
    '';
    uv.enable = true;
  };

  languages.rust = {
    enable = true;
    channel = "nightly";
    rustflags = "-Z threads=8";
    targets = [ "wasm32-unknown-unknown" ];
  };

  languages.php = {
    enable = true;
    version = "8.1";
    ini = ''
      memory_limit = 256M
    '';
    fpm.pools.web = {
      settings = {
        "pm" = "dynamic";
      };
    };
  };
}
devenv.nix
{ pkgs, ... }: {
  packages = [
    pkgs.cargo-watch
  ];

  processes = {
    cargo-watch.exec = "cargo watch -x run";
  };
}
devenv up
• Building processes ...
• Starting processes ...
...

Run processes

Define your processes declaratively and start them with devenv up.

Declarative processes
Inspired by Procfile, define development processes that have access to your environment.
Process management
By default process-compose is used to manage processes, giving you a simple interface to inspect logs and restart processes (Ctrl+R). Process compose interface

Run services

Choose from many community-maintained services like PostgreSQL, Redis, MySQL, RabbitMQ, WireMock, MinIO, Caddy, ElasticSearch, OpenTelemetry Collector, Prometheus, and more added regularly.

Pre-configured processes
Services define processes that start automatically when enabled via devenv up.
Simple configuration
Each service provides various configuration options and hooks to pass additional custom configuration.
Extensible
Define your own development processes as services, enabling simple reuse with minimal configuration.
devenv.nix
{ pkgs, ... }: {
  services.postgres = {
    enable = true;
    package = pkgs.postgresql_15;
    initialDatabases = [{ name = "mydb"; }];
    extensions = extensions: [
      extensions.postgis
      extensions.timescaledb
    ];
    settings.shared_preload_libraries = "timescaledb";
    initialScript = "CREATE EXTENSION IF NOT EXISTS timescaledb;";
  };
}
devenv up
...

devenv.nix
{ pkgs, ... }: {
  packages = [
    pkgs.mkdocs
    pkgs.curl
  ];

  processes = {
    docs.exec = "mkdocs serve";
  };

  enterTest = ''
    wait_for_port 8000
    curl http://localhost:8000 | grep "Hello, world!"
  '';
}
devenv test
...

Run tests

Running scripts in your environment with all processes active is as simple as devenv test.

Integrated testing
Execute your preferred language test runner or a simple script to verify your environment.

All process management is handled automatically, so you can focus on writing tests.

Container interoperability

Generate containers from your development environment and build/copy/run them.

Containerized environments
The shell container lets you run your environment in a container.

Use devenv container run shell to enter your environment in a container.

Containerized processes
The processes container lets you run your processes in a container.

Use devenv container run processes to run your processes in a container.

Custom containers
Define containers.mycontainer.* to customize your container.
devenv.nix
{ pkgs, ... }: {
  packages = [
    pkgs.mkdocs
    pkgs.curl
  ];

  processes = {
    docs.exec = "mkdocs serve";
  };
}
devenv container build processes
...
devenv container copy processes
...
devenv container run processes
...

devenv.yaml
inputs:
  myorg-devenv:
    url: github:myorg/myorg-devenv
imports:
  - ./frontend
  - ./backend
  - myorg-devenv/service1
  - myorg-devenv/service2

Poly/Mono repo composability

Compose multiple environments into a single environment.

Local imports
For monorepos, define environments per folder and import them to merge into a single unified environment.
Remote imports
For polyrepos, define environments per repository and import them to merge into a single unified environment.

Start with a central repository containing shared configuration until your team is comfortable maintaining their own environments.

Get Started