devenv
Use this when working in a project with devenv.nix, or when devenv.sh development environment setup, services, dependencies, or Nix packages are relevant.
Install
npx skills add https://github.com/kissgyorgy/coding-agents/tree/master/skills/devenv
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install kissgyorgy-coding-agents@llmmart
git clone https://github.com/kissgyorgy/coding-agents.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole kissgyorgy/coding-agents collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
devenv.sh Development Environments
Create fast, declarative, reproducible development environments using devenv.sh powered by Nix. Official docs: https://devenv.sh
For setting up specific programming languages, services, package managers, see:
- python-uv.md - Detailed Python/uv configuration
- services.md - Complete services configuration guide
- django.md - Django project setup and patterns
Initialize a New Environment
devenv init
This creates:
devenv.yaml- Input configurationdevenv.nix- Environment definition (where you configure everything).envrc- direnv integration.gitignore- Ignores devenv artifacts
Remove comments from .gitignore after init.
The generated .envrc from devenv init works as-is now; you no longer need
the old task-running workaround.
Edit devenv.yaml and replace the inputs section:
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixpkgs-unstable
This gives access to the latest packages from nixpkgs.
Adding Nix Packages
Add system packages to your environment:
{ pkgs, ... }: {
packages = with pkgs; [
just # always add this
postgresql # For psql CLI
redis # For redis-cli
];
}
Search for packages:
devenv search <package-name>
Only works after devenv init
Update Lock File
After changing inputs:
devenv update
This updates devenv.lock with pinned versions.
IMPORTANT: ALWAYS run devenv build after editing devenv.nix to make sure the configuration is working.
Fix any problems that occurs during build.
Environment Variables
{
env = {
MY_VAR = "value";
PYTHONUNBUFFERED = "1";
};
}
Common Commands
devenv init- Initialize new environmentdevenv shell- Enter development shelldevenv up- Start services and processes (foreground)devenv up -d- Start services in backgrounddevenv processes stop- Stop all processesdevenv test- Run testsdevenv update- Update dependencies from devenv.yamldevenv search <pkg>- Search for packagesdevenv info- Show environment info
File Structure
Key files devenv manages:
devenv.nix- Your environment configuration (commit this)devenv.yaml- Input sources (commit this)devenv.lock- Pinned versions (commit this).envrc- direnv integration (commit this).devenv/- Build artifacts (don't commit)
Complete Example
{ pkgs, config, ... }: {
# Python with uv
languages.python = {
enable = true;
version = "3.12";
uv = {
enable = true;
sync.enable = true;
};
venv.enable = true; # Activate the synced virtualenv in shell/direnv
libraries = with pkgs; [ postgresql stdenv.cc.cc.lib ];
};
# Services
services = {
postgres = {
enable = true;
package = pkgs.postgresql_15;
initialDatabases = [{ name = "app"; }];
};
redis.enable = true;
};
# Packages
packages = with pkgs; [
git
postgresql
redis
];
# Environment
env = {
DATABASE_URL = "postgresql://localhost/app";
REDIS_URL = "redis://localhost:6379";
};
# Processes (devenv 2.0 native process manager with dependency support)
processes = {
web = {
exec = "python manage.py runserver 0.0.0.0:8000";
after = [ "devenv:processes:postgres" "devenv:processes:redis" ];
};
worker = {
exec = "celery -A myapp worker";
after = [ "devenv:processes:redis" ];
};
};
# Scripts
scripts = {
migrate = {
exec = "python manage.py migrate";
description = "Run migrations";
};
test = {
exec = "pytest";
description = "Run tests";
};
};
# Enable dotenv
dotenv.enable = true;
}
Troubleshooting
Issue: Package not found
Search for it:
devenv search <package>
Ensure using nixpkgs-unstable in devenv.yaml.
Issue: Python virtualenv is not activated
For Python projects using uv, set both languages.python.uv.sync.enable = true and languages.python.venv.enable = true. uv.sync installs dependencies; venv.enable activates the virtualenv so python and console scripts come from the project environment.
Issue: Python package won't install
Add native dependencies to languages.python.libraries:
{
languages.python.libraries = with pkgs; [
postgresql # For psycopg2
stdenv.cc.cc.lib
];
}
Files (coding-agents)
-
django.md 4.6 KB
# Django Project Setup # Django Workflow 1. Initialize devenv (if not yet initialized): `devenv init` 2. Configure `devenv.nix` as above, including `languages.python.venv.enable = true` 3. Update `devenv.yaml` to use nixpkgs-unstable 4. Enter shell: `devenv shell` 5. Add Django: `uv add django` 6. Create project: `uv run django-admin startproject myproject .` 7. In another terminal: `devenv shell` then `python manage.py migrate` ## Complete Django + PostgreSQL Environment ### Minimal Django Setup ```nix { pkgs, ... }: { languages.python = { enable = true; uv = { enable = true; sync.enable = true; }; venv.enable = true; libraries = with pkgs; [ postgresql ]; }; services.postgres = { enable = true; initialDatabases = [ { name = "myproject_dev"; } ]; }; env = { DATABASE_URL = "postgresql://localhost/myproject_dev"; DJANGO_SETTINGS_MODULE = "myproject.settings"; PYTHONUNBUFFERED = "1"; }; processes = { django = { exec = "python manage.py runserver"; process-compose = { depends_on = { postgres = { condition = "process_healthy"; }; }; }; }; }; } ``` ### 5. Create Django project If using uv: ```bash # Initialize uv project (if not done yet) uv init . # Add Django and database driver uv add django psycopg2-binary # Create Django project uv run django-admin startproject myproject . ``` Or with traditional venv: ```bash # Django will be available from venv django-admin startproject myproject . ``` ### 6. Configure Django Database Edit `myproject/settings.py`: ```python import os from pathlib import Path # Use environment variable for database DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('PGDATABASE', 'myproject_dev'), 'USER': os.environ.get('PGUSER', os.environ.get('USER')), 'PASSWORD': os.environ.get('PGPASSWORD', ''), 'HOST': os.environ.get('PGHOST', ''), 'PORT': os.environ.get('PGPORT', '5432'), } } ``` This starts both PostgreSQL and Django together. ## Advanced Django Configuration ### Multiple Processes (Django + Celery) ```nix { pkgs, ... }: { languages.python = { enable = true; version = "3.12"; uv = { enable = true; sync.enable = true; }; venv.enable = true; }; services = { postgres = { enable = true; initialDatabases = [{ name = "myapp"; }]; }; redis = { enable = true; }; }; processes = { django = { exec = "python manage.py runserver 0.0.0.0:8000"; process-compose.depends_on = { postgres.condition = "process_healthy"; redis.condition = "process_healthy"; }; }; celery-worker = { exec = "celery -A myproject worker --loglevel=info"; process-compose.depends_on = { postgres.condition = "process_healthy"; redis.condition = "process_healthy"; }; }; celery-beat = { exec = "celery -A myproject beat --loglevel=info"; process-compose.depends_on = { celery-worker.condition = "process_started"; }; }; }; } ``` ### Django with Static Files / Tailwind ```nix { pkgs, ... }: { languages.python = { enable = true; version = "3.12"; uv.enable = true; uv.sync.enable = true; venv.enable = true; }; services.postgres = { enable = true; initialDatabases = [{ name = "myapp"; }]; }; # Add Node.js for Tailwind/frontend tools packages = with pkgs; [ nodejs_22 bun ]; processes = { django = { exec = "python manage.py runserver"; }; tailwind = { exec = "bun run dev"; # or python manage.py tailwind start cwd = "./frontend"; }; }; } ``` ## Common Django Packages Add to `pyproject.toml` or via uv: ```bash # Core uv add django # Admin enhancements uv add django-debug-toolbar django-extensions # API uv add djangorestframework django-cors-headers # Task queue uv add celery redis # Development tools uv add --group dev pytest pytest-django pytest-sugar # Static files uv add whitenoise ``` ## Troubleshooting ### PostgreSQL Connection Issues Ensure environment variables are set: ```bash echo $PGHOST echo $PGPORT echo $PGDATABASE ``` Test connection: ```bash psql -d myproject_dev ``` ### Migration Issues If migrations fail due to database state: ```bash # Reset database devenv processes stop rm -rf .devenv/state/postgres devenv up -d # Re-run migrations python manage.py migrate ``` ### Port Already in Use Change Django's default port: ```nix { processes.django.exec = "python manage.py runserver 0.0.0.0:8001"; } ``` -
envrc 92 B · in bundle
-
python-uv.md 2.7 KB
# Python and uv Configuration ## Basic Python Setup Enable Python with the latest Python version: ```nix { languages.python = { enable = true; }; } ``` ## uv Integration For Python projects using uv, enable both `uv.sync.enable` and `venv.enable`. `uv.sync.enable` installs dependencies from `pyproject.toml` / `uv.lock`, while `venv.enable` activates that virtual environment in `devenv shell` / direnv (`VIRTUAL_ENV` is set and the venv `bin` directory is added to `PATH`). ### Basic uv Setup Enable uv package manager: ```nix { languages.python = { enable = true; uv.enable = true; venv.enable = true; }; } ``` ### uv with sync Support For projects with `pyproject.toml`, enable `uv sync`: ```nix { languages.python = { enable = true; version = "3.11"; uv = { enable = true; sync.enable = true; }; venv.enable = true; }; } ``` This automatically runs `uv sync` when entering the shell, installing dependencies from `pyproject.toml` and `uv.lock`, and activates the resulting virtual environment. ### Advanced uv Configuration ```nix { languages.python = { enable = true; version = "3.12"; uv = { enable = true; sync = { enable = true; allExtras = true; # Install all extras allGroups = true; # Install all dependency groups # Specific extras/groups: extras = [ "dev" "test" ]; groups = [ "dev" ]; }; }; venv.enable = true; }; } ``` ## Adding System-Level Native Libraries Some Python packages need native libraries (e.g., PostgreSQL development headers, Pillow image libraries, etc.): ```nix { pkgs, ... }: { languages.python = { enable = true; version = "3.11"; libraries = with pkgs; [ # For psycopg2: postgresql # For Pillow: libjpeg zlib # For lxml: libxml2 libxslt ]; }; } ``` ## Workflow with uv 1. **Initialize a new project:** ```bash uv init myproject cd myproject ``` 2. **Add dependencies:** ```bash uv add django uv add psycopg2-binary uv add --group dev pytest ``` 3. **Devenv will auto-sync on shell entry** when `uv.sync.enable = true` 4. **Devenv will activate the virtual environment** when `venv.enable = true`, so bare commands like `python`, `django-admin`, and console scripts use project dependencies. 5. **Manual sync if needed:** ```bash uv sync ``` ## Troubleshooting ### Issue: Native library not found Add the required library to `languages.python.libraries`. Common libraries: - PostgreSQL: `postgresql` - MySQL: `mysql80` - Image processing: `libjpeg`, `zlib`, `libpng` - XML: `libxml2`, `libxslt` -
services.md 8 KB
# Services and Processes Configuration (devenv 2.0) ## Basic configuration Define processes that run with `devenv up`: ```nix { pkgs, ... }: { processes = { web.exec = "python manage.py runserver"; worker.exec = "celery -A myapp worker"; }; } ``` devenv 2.0 uses its own **native process manager** by default with a built-in TUI. Alternative managers (process-compose, mprocs, overmind, etc.) are available but rarely needed: ```nix { process.manager.implementation = "process-compose"; # only if explicitly needed } ``` ## Process Dependencies Processes can depend on other processes using `after`: ```nix { processes.api = { exec = "myapi"; after = [ "devenv:processes:database" ]; # wait for database to be @ready (default) }; } ``` Dependency suffixes for **processes**: `@started`, `@ready` (default), `@completed` Dependency suffixes for **tasks**: `@started`, `@succeeded` (default), `@completed` ## Ready Probes devenv 2.0 supports readiness probes that dependencies wait for: ### Exec probe ```nix { processes.database = { exec = "postgres -D $PGDATA"; ready.exec = "pg_isready -d template1"; }; } ``` ### HTTP probe ```nix { processes.api = { exec = "myserver"; ready.http.get = { port = 8080; path = "/health"; }; }; } ``` ### Notify probe (systemd-style) ```nix { processes.database = { exec = "postgres"; ready.notify = true; # process sends READY=1 to $NOTIFY_SOCKET }; } ``` ### Probe timing options ```nix { processes.api = { exec = "myserver"; ready = { http.get = { port = 8080; path = "/health"; }; initial_delay = 2; # seconds before first probe (default: 0) period = 10; # seconds between probes (default: 10) timeout = 1; # seconds before probe times out (default: 1) success_threshold = 1; # consecutive successes needed (default: 1) failure_threshold = 3; # consecutive failures before unhealthy (default: 3) }; }; } ``` When `listen` sockets or allocated `ports` are configured and no explicit probe is set, a TCP connectivity check is used automatically. ## Restart Policies ```nix { processes.worker = { exec = "worker --queue jobs"; restart = { on = "on_failure"; # "on_failure" (default), "always", "never" max = 5; # null for unlimited (default: 5) }; }; } ``` ## Automatic Port Allocation devenv 2.0 can auto-allocate free ports to avoid conflicts: ```nix { config, ... }: { processes.server = { ports.http.allocate = 8080; # starts from 8080, finds next free exec = '' python -m http.server ${toString config.processes.server.ports.http.value} ''; }; } ``` ## File Watching ```nix { processes.backend = { exec = "cargo run"; watch = { paths = [ ./src ]; extensions = [ "rs" "toml" ]; ignore = [ "target" "*.log" ]; }; }; } ``` ## Service examples ### Basic PostgreSQL Setup ```nix { pkgs, ... }: { services.postgres.enable = true; } ``` This starts PostgreSQL with default settings: - Port: 5432 (auto-allocated if busy) - Data directory: `$DEVENV_STATE/postgres` - Unix socket: `$DEVENV_RUNTIME/postgres` - Built-in readiness probe using `pg_isready` + `psql` **IMPORTANT:** Do NOT override `processes.postgres.exec` — the upstream service module handles initialization, config management, database creation, and readiness probes correctly. Only use `services.postgres.*` options to configure PostgreSQL. ### PostgreSQL with Initial Databases ```nix { pkgs, ... }: { services.postgres = { enable = true; initialDatabases = [ { name = "myapp_dev"; } { name = "myapp_test"; } ]; }; } ``` ### PostgreSQL with Extensions ```nix { pkgs, ... }: { services.postgres = { enable = true; initialDatabases = [ { name = "mydb"; } ]; extensions = ext: [ ext.postgis ext.timescaledb ext.pg_uuidv7 ]; settings = { shared_preload_libraries = "timescaledb"; }; initialScript = '' CREATE EXTENSION IF NOT EXISTS timescaledb; CREATE EXTENSION IF NOT EXISTS postgis; ''; }; } ``` ### PostgreSQL with Initial Schema ```nix { pkgs, ... }: { services.postgres = { enable = true; initialDatabases = [ { name = "mydb"; schema = ./schema.sql; } ]; }; } ``` ### PostgreSQL with Initialization SQL ```nix { pkgs, ... }: { services.postgres = { enable = true; initialDatabases = [ { name = "appdb"; initialSQL = '' CREATE TABLE users ( id SERIAL PRIMARY KEY, username TEXT NOT NULL, email TEXT UNIQUE NOT NULL ); ''; } ]; }; } ``` ### PostgreSQL Environment Variables Devenv automatically sets these environment variables: - `PGDATA`: Points to the database directory - `PGHOST`: Points to the socket directory or listen address - `PGPORT`: The configured port (auto-allocated) ```bash psql -d mydb ``` ### PostgreSQL Configuration Settings ```nix { pkgs, ... }: { services.postgres = { enable = true; settings = { max_connections = 100; shared_buffers = "128MB"; log_statement = "all"; log_destination = "stderr"; logging_collector = true; }; }; } ``` ### PostgreSQL Listen on Network By default, PostgreSQL only listens on Unix sockets. To listen on network: ```nix { pkgs, ... }: { services.postgres = { enable = true; listen_addresses = "127.0.0.1"; # or "0.0.0.0" for all interfaces port = 5432; }; } ``` ### PostgreSQL with Database Owner ```nix { pkgs, ... }: { services.postgres = { enable = true; initialDatabases = [ { name = "appdb"; user = "appuser"; pass = "secret"; } ]; }; } ``` ## Other Common Services ### Redis ```nix { pkgs, ... }: { services.redis = { enable = true; port = 6379; }; } ``` ### MySQL ```nix { pkgs, ... }: { services.mysql = { enable = true; package = pkgs.mysql80; initialDatabases = [ { name = "mydb"; } ]; }; } ``` ### MongoDB ```nix { pkgs, ... }: { services.mongodb.enable = true; } ``` ### Nginx ```nix { pkgs, ... }: { services.nginx = { enable = true; httpConfig = '' server { listen 8080; location / { proxy_pass http://localhost:8000; } } ''; }; } ``` ### Caddy ```nix { pkgs, ... }: { services.caddy = { enable = true; config = '' localhost:8080 { reverse_proxy localhost:8000 } ''; }; } ``` ## Service State Management Services store their state in `$DEVENV_STATE/<service-name>`. For example: - PostgreSQL: `$DEVENV_STATE/postgres` - Redis: `$DEVENV_STATE/redis` ### Resetting Service State If you need to reset a service (e.g., after changing `initialScript`): ```bash devenv processes stop rm -rf .devenv/state/postgres devenv up ``` ## Starting and Stopping Services ```bash devenv up # Foreground with TUI devenv up -d # Background (detached) devenv processes stop # Stop background processes devenv processes wait --timeout 120 # Wait for all processes to be ready (CI) ``` ## Troubleshooting ### Issue: "not ready: exec" for a service The readiness probe command is failing. Debug by running the probe manually: ```bash pg_isready -d template1 # for postgres ``` Common causes: - PGHOST/PGPORT env vars don't match how postgres was started - Stale process from a previous session — kill it and restart - Custom `processes.<service>.exec` override conflicts with the service's readiness probe **Fix:** Remove any custom `processes.<service>.exec` overrides and use the service's built-in options instead. devenv 2.0 services handle startup, config, and readiness probes correctly. ### Issue: Process won't stop ```bash devenv processes stop # If that doesn't work: pkill -f "devenv" ``` ### Issue: Changes to services not taking effect Service state is cached. Reset it: ```bash devenv processes stop rm -rf .devenv/state/postgres devenv up ``` -
setup.md 965 B
# Initialize a New Environment ```bash devenv init ``` This creates: - `devenv.yaml` - Input configuration - `devenv.nix` - Environment definition (where you configure everything) - `.envrc` - direnv integration - `.gitignore` - Ignores devenv artifacts Remove comments from .gitignore after init. ## Use nixpkgs-unstable Instead of devenv-rolling Edit `devenv.yaml` and replace the inputs section: ```yaml inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable ``` This gives access to the latest packages from nixpkgs. ## Update Lock File After changing inputs: ```bash devenv update ``` This updates `devenv.lock` with pinned versions. ## Python and uv Setup Configure in `devenv.nix`: ```nix { pkgs, ... }: { languages.python = { enable = true; venv.enable = true; # uv will use the activated virtualenv uv = { enable = true; sync.enable = true; # Auto-sync pyproject.toml on shell entry }; }; } ``` -
SKILL.md 4.6 KB
--- name: devenv description: Use this when working in a project with devenv.nix, or when devenv.sh development environment setup, services, dependencies, or Nix packages are relevant. --- # devenv.sh Development Environments Create fast, declarative, reproducible development environments using devenv.sh powered by Nix. Official docs: https://devenv.sh For setting up specific programming languages, services, package managers, see: - **[python-uv.md](python-uv.md)** - Detailed Python/uv configuration - **[services.md](services.md)** - Complete services configuration guide - **[django.md](django.md)** - Django project setup and patterns ## Initialize a New Environment ```bash devenv init ``` This creates: - `devenv.yaml` - Input configuration - `devenv.nix` - Environment definition (where you configure everything) - `.envrc` - direnv integration - `.gitignore` - Ignores devenv artifacts Remove comments from .gitignore after init. The generated `.envrc` from `devenv init` works as-is now; you no longer need the old task-running workaround. Edit `devenv.yaml` and replace the inputs section: ```yaml inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable ``` This gives access to the latest packages from nixpkgs. ## Adding Nix Packages Add system packages to your environment: ```nix { pkgs, ... }: { packages = with pkgs; [ just # always add this postgresql # For psql CLI redis # For redis-cli ]; } ``` Search for packages: ```bash devenv search <package-name> ``` Only works after `devenv init` ## Update Lock File After changing inputs: ```bash devenv update ``` This updates `devenv.lock` with pinned versions. IMPORTANT: ALWAYS run `devenv build` after editing `devenv.nix` to make sure the configuration is working. Fix any problems that occurs during build. ## Environment Variables ```nix { env = { MY_VAR = "value"; PYTHONUNBUFFERED = "1"; }; } ``` ## Common Commands - `devenv init` - Initialize new environment - `devenv shell` - Enter development shell - `devenv up` - Start services and processes (foreground) - `devenv up -d` - Start services in background - `devenv processes stop` - Stop all processes - `devenv test` - Run tests - `devenv update` - Update dependencies from devenv.yaml - `devenv search <pkg>` - Search for packages - `devenv info` - Show environment info ## File Structure Key files devenv manages: - `devenv.nix` - Your environment configuration (commit this) - `devenv.yaml` - Input sources (commit this) - `devenv.lock` - Pinned versions (commit this) - `.envrc` - direnv integration (commit this) - `.devenv/` - Build artifacts (don't commit) ## Complete Example ```nix { pkgs, config, ... }: { # Python with uv languages.python = { enable = true; version = "3.12"; uv = { enable = true; sync.enable = true; }; venv.enable = true; # Activate the synced virtualenv in shell/direnv libraries = with pkgs; [ postgresql stdenv.cc.cc.lib ]; }; # Services services = { postgres = { enable = true; package = pkgs.postgresql_15; initialDatabases = [{ name = "app"; }]; }; redis.enable = true; }; # Packages packages = with pkgs; [ git postgresql redis ]; # Environment env = { DATABASE_URL = "postgresql://localhost/app"; REDIS_URL = "redis://localhost:6379"; }; # Processes (devenv 2.0 native process manager with dependency support) processes = { web = { exec = "python manage.py runserver 0.0.0.0:8000"; after = [ "devenv:processes:postgres" "devenv:processes:redis" ]; }; worker = { exec = "celery -A myapp worker"; after = [ "devenv:processes:redis" ]; }; }; # Scripts scripts = { migrate = { exec = "python manage.py migrate"; description = "Run migrations"; }; test = { exec = "pytest"; description = "Run tests"; }; }; # Enable dotenv dotenv.enable = true; } ``` ## Troubleshooting ### Issue: Package not found Search for it: ```bash devenv search <package> ``` Ensure using nixpkgs-unstable in `devenv.yaml`. ### Issue: Python virtualenv is not activated For Python projects using uv, set both `languages.python.uv.sync.enable = true` and `languages.python.venv.enable = true`. `uv.sync` installs dependencies; `venv.enable` activates the virtualenv so `python` and console scripts come from the project environment. ### Issue: Python package won't install Add native dependencies to `languages.python.libraries`: ```nix { languages.python.libraries = with pkgs; [ postgresql # For psycopg2 stdenv.cc.cc.lib ]; } ```
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.