devenv + direnv Repository Onboarding
Prerequisites
Before onboarding, ensure:
- Nix is installed:
sh <(curl -L https://nixos.org/nix/install) --daemon - devenv is installed:
nix-env --install --attr devenv -f https://github.com/NixOS/nixpkgs/tarball/nixpkgs-unstable - direnv is installed and hooked in the shell (e.g.
eval "$(direnv hook zsh)"in~/.zshrc)
Onboarding Workflow
1. Initialize devenv
cd /path/to/repository
devenv init
Creates: devenv.nix, devenv.yaml, and .gitignore (with .direnv added to it so the direnv cache directory is not committed). Does not create .envrc — create it manually.
2. Configure .envrc for direnv
Create or update .envrc in the project root:
export DIRENV_WARN_TIMEOUT=20s
eval "$(devenv direnvrc)"
use devenv
Optional: pass flags to devenv for overrides, e.g. use devenv --option services.postgres.enable:bool true
3. Approve and load
direnv allow
User must run this once per repo to approve the .envrc. After that, the environment loads automatically when entering the directory.
4. Verify
devenv shell # manually enter shell if needed
devenv test # run environment tests
File Structure
| File | Purpose |
|---|---|
.envrc |
direnv activation; loads devenv when entering directory |
devenv.yaml |
Inputs (nixpkgs, modules); similar to flake inputs |
devenv.nix |
Environment definition (packages, env vars, languages, services, scripts) |
devenv.lock |
Pinned inputs; generated by devenv update |
devenv.yaml Basics
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixpkgs-unstable
Add other inputs (e.g. devenv modules) as needed.
devenv.nix by Language
Use only the language blocks relevant to your project.
Rust
languages.rust.enable = true;
languages.rust.channel = "stable"; # or "beta", "nightly"
# Optional: additional Rust tools
packages = [ pkgs.cargo-nextest pkgs.sqlx-cli ];
JavaScript / Node.js
languages.javascript.enable = true;
languages.javascript.npm.enable = true;
# Optional: Node version
# languages.javascript.package = pkgs.nodejs_20;
Python
languages.python.enable = true;
languages.python.version = "3.11";
# Optional: pip/venv
# languages.python.venv.enable = true;
Java
languages.java.enable = true;
# Build tool — choose one:
languages.java.maven.enable = true; # Maven
# languages.java.gradle.enable = true; # Gradle
Go
languages.go.enable = true;
languages.go.version = "1.21";
Common extras (any language)
{ pkgs, ... }:
{
dotenv.enable = true;
packages = [ pkgs.git pkgs.openssl ];
services.postgres = {
enable = true;
port = 5433;
initialDatabases = [{ name = "myapp"; }];
};
env.DATABASE_URL = "postgres://localhost:5433/myapp";
scripts.lint.exec = ''...'';
scripts.test.exec = ''...'';
}
Cachix (Binary Caching)
Devenv integrates with Cachix for binary caching. No separate Cachix client needed; devenv handles it. devenv.cachix.org is added by default (mirrors NixOS cache).
Pull from a cache
Add cache names to devenv.nix:
{
cachix.pull = [ "mycache" ];
}
Push to your cache
- Create a cache at cachix.org
- Set auth:
export CACHIX_AUTH_TOKEN=XXX(orcachix authtoken XXX) - In
devenv.nix:
{
cachix.push = "mycache";
}
To push only in CI, use devenv.local.nix (gitignored): echo '{ cachix.push = "mycache"; }' > devenv.local.nix
Disable Cachix
{
cachix.enable = false;
}
Common Commands
| Command | Purpose |
|---|---|
devenv init |
Create initial config files |
devenv shell |
Enter environment manually |
devenv update |
Update and pin inputs to devenv.lock |
devenv gc |
Garbage collect unused envs |
devenv test |
Build and run tests (CI-friendly) |
direnv allow |
Approve .envrc (run once per repo) |
Troubleshooting
- "direnv: error ... is blocked" → Run
direnv allow - Slow first load → Normal; Nix builds the environment once
DIRENV_WARN_TIMEOUT→ Increase if builds are slow (e.g.30s)- GitHub rate limiting → Add
access-tokens = github.com=<TOKEN>to~/.config/nix/nix.conf