What is Devbox?
Devbox is a command-line tool that creates isolated, reproducible development environments for any project. Built by Jetpack.io, it uses Nix to provide instant, portable shells with all the tools and dependencies your project needs.
The core problem Devbox solves is environment consistency. How many times have you heard “it works on my machine”? Different developers have different versions of Node, Python, or Go installed. System libraries vary between macOS and Linux. Dependencies conflict between projects. Devbox eliminates these issues entirely.
“Devbox creates isolated shells for development. You can define the list of packages required for your project, and Devbox will install them in a local directory and create an isolated shell environment.”
— Jetpack.io Documentation
Unlike Docker, which creates containerised environments, Devbox runs packages natively on your machine. This means faster startup times, direct access to your filesystem, and smooth integration with your existing tools and IDEs.
How Devbox Works
Under the hood, Devbox uses Nix, the purely functional package manager. Nix provides several guarantees that make reproducible environments possible:
Deterministic Builds
Every package is built with its complete dependency tree, ensuring the same inputs always produce the same outputs.
Isolated Packages
Packages are stored in isolation with unique hashes. Multiple versions can coexist without conflicts.
Massive Package Repository
Nixpkgs contains over 100,000 packages, from programming languages to databases to command-line utilities.
Cross-Platform Support
The same devbox.json works on macOS, Linux, and Windows (via WSL2), ensuring true cross-platform reproducibility.
The beauty of Devbox is that it abstracts away Nix's complexity. You don't need to learn the Nix expression language or understand its package derivations. Devbox provides a simple JSON configuration and intuitive commands.
# The workflow is simple: $ devbox init # Create devbox.json $ devbox add nodejs # Add packages $ devbox shell # Enter the environment # That's it! Your isolated environment is ready.
Installing Devbox
Installing Devbox is straightforward. It automatically installs Nix if needed, so you don't need to set it up separately.
Quick Install (Recommended)
# Install Devbox with the official installer curl -fsSL https://get.jetpack.io/devbox | bash # Verify installation devbox version
Alternative Installation Methods
# Using Homebrew (macOS/Linux) brew install jetpack-io/devbox/devbox # Using Nix (if you already have Nix installed) nix-env -iA nixpkgs.devbox # Using Nixpkgs flakes nix profile install nixpkgs#devbox
Note for Windows Users
Devbox requires WSL2 on Windows. Install WSL2 first, then run the installation command inside your WSL2 distribution.
Creating devbox.json
The devbox.json file is the heart of your Devbox configuration. It defines packages, environment variables, shell hooks, and scripts for your project.
Initialising a New Project
# Navigate to your project directory cd my-project # Initialise Devbox devbox init # This creates devbox.json and devbox.lock
Example devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetpack-io/devbox/main/.schema/devbox.schema.json",
"packages": [
"nodejs@20",
"python@3.12",
"postgresql@15",
"redis@7"
],
"env": {
"DATABASE_URL": "postgresql://localhost:5432/myapp_dev",
"REDIS_URL": "redis://localhost:6379",
"NODE_ENV": "development"
},
"shell": {
"init_hook": [
"echo 'Welcome to the development environment!'",
"export PATH=$PWD/node_modules/.bin:$PATH"
],
"scripts": {
"dev": "npm run dev",
"test": "npm test",
"lint": "eslint . --ext .ts,.tsx",
"db:migrate": "prisma migrate dev",
"db:seed": "prisma db seed"
}
}
}The devbox.lock file is generated automatically and pins exact package versions. Always commit both files to version control for reproducibility.
Adding Packages
Devbox provides access to over 100,000 packages from the Nixpkgs repository. Usedevbox add to install packages.
Basic Package Management
# Add a package (latest version) devbox add nodejs # Add a specific version devbox add nodejs@20 devbox add python@3.12.1 # Add multiple packages at once devbox add go@1.21 rustc cargo # Search for packages devbox search postgresql # Remove a package devbox rm nodejs # List installed packages devbox list
Common Package Examples
# Web Development devbox add nodejs@20 yarn pnpm typescript # Python Development devbox add python@3.12 poetry pipenv # Go Development devbox add go@1.21 golangci-lint gopls # Rust Development devbox add rustc cargo rust-analyzer # DevOps Tools devbox add terraform kubectl helm awscli # Databases devbox add postgresql@15 mysql@8 redis@7 mongodb@6 # Utilities devbox add git jq yq ripgrep fd curl wget
Finding Package Names
Use devbox search <name> to find available packages, or browse the Nixpkgs repository at search.nixos.org/packages.
Local vs Global Configuration
Devbox supports two configuration scopes: local (project-level) and global (user-level). Understanding when to use each helps you organise your development tools effectively.
Local (Project)
Project-specific packages defined in devbox.json at the repository root. Shared with your team via version control.
- ✓Project-specific language runtimes (Node, Python, Go)
- ✓Databases and services needed for the project
- ✓Build tools and project dependencies
- ✓Committed to git, shared across team
Global (User)
User-wide packages available in any terminal session. Stored in~/.local/share/devbox/global.
- ✓General CLI tools (ripgrep, jq, fd, bat)
- ✓Cloud CLIs (aws, gcloud, az)
- ✓Infrastructure tools (terraform, kubectl)
- ✓Personal to your machine, not shared
Setting Up Global Devbox
Global packages are available system-wide without entering a project-specific shell. Perfect for tools you use across all projects.
# Add packages globally devbox global add ripgrep fd bat jq yq devbox global add terraform kubectl helm devbox global add awscli google-cloud-sdk azure-cli # List global packages devbox global list # Remove a global package devbox global rm terraform # View global configuration path devbox global path # Output: ~/.local/share/devbox/global # Edit global devbox.json directly devbox global edit
Activating Global Packages
To make global packages available in every terminal session, add the shellenv to your shell profile:
# For Zsh (add to ~/.zshrc) eval "$(devbox global shellenv)" # For Bash (add to ~/.bashrc) eval "$(devbox global shellenv)" # For Fish (add to ~/.config/fish/config.fish) devbox global shellenv | source # Reload your shell source ~/.zshrc # or ~/.bashrc
Global Configuration File
The global configuration works just like project configuration but applies everywhere:
# ~/.local/share/devbox/global/devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetpack-io/devbox/main/.schema/devbox.schema.json",
"packages": [
"ripgrep@14",
"fd@9",
"bat@0.24",
"jq@1.7",
"yq@4",
"terraform@1.6",
"kubectl@1.28",
"awscli2@2",
"git@2.43",
"gh@2"
],
"env": {
"EDITOR": "vim",
"AWS_PAGER": ""
},
"shell": {
"init_hook": [
"# Global shell customisations",
"alias ll='ls -la'",
"alias k='kubectl'",
"alias tf='terraform'"
]
}
}Local Project Configuration
Local configuration is stored in your project directory and should be committed to git:
# Create local config in your project cd ~/projects/my-web-app devbox init # Add project-specific packages devbox add nodejs@20 pnpm typescript devbox add postgresql@15 redis@7 # Your project now has: # ./devbox.json - Configuration (commit this) # ./devbox.lock - Lock file (commit this) # Enter the project shell devbox shell # Packages from BOTH local and global are available! node --version # From local config rg --version # From global config
How Local and Global Interact
When you run devbox shell in a project directory, Devbox combines packages from both local and global configurations:
- Local packages take precedence if there's a version conflict
- Global packages are available as a fallback for common tools
- Environment variables from both are merged (local wins on conflict)
- Init hooks from both are executed (global first, then local)
# Example workflow $ devbox global add ripgrep jq # Available everywhere $ cd ~/projects/api $ devbox init $ devbox add nodejs@20 postgresql # Only in this project $ devbox shell # Now you have: nodejs, postgresql (local) + ripgrep, jq (global) $ cd ~/projects/python-app $ devbox init $ devbox add python@3.12 poetry # Only in this project $ devbox shell # Now you have: python, poetry (local) + ripgrep, jq (global) # nodejs is NOT available here - it was local to the api project
Shell Hooks and Init Hooks
Hooks allow you to run commands automatically when entering the Devbox shell. Use them to set up your environment, display welcome messages, or run initialisation scripts.
Init Hook Configuration
{
"packages": ["nodejs@20", "python@3.12"],
"shell": {
"init_hook": [
"# Display environment info",
"echo '🚀 Development environment ready!'",
"echo 'Node version:' $(node --version)",
"echo 'Python version:' $(python --version)",
"",
"# Set up Python virtual environment",
"if [ ! -d .venv ]; then",
" python -m venv .venv",
"fi",
"source .venv/bin/activate",
"",
"# Install dependencies if needed",
"if [ -f package.json ] && [ ! -d node_modules ]; then",
" npm install",
"fi",
"",
"# Add local bin to PATH",
"export PATH=$PWD/node_modules/.bin:$PWD/.venv/bin:$PATH"
]
}
}Using External Scripts
For complex setup logic, reference an external script file:
{
"packages": ["nodejs@20"],
"shell": {
"init_hook": [
". ./scripts/devbox-init.sh"
]
}
}#!/bin/bash # Load environment-specific configuration if [ -f .env.local ]; then export $(cat .env.local | xargs) fi # Check for required tools command -v docker >/dev/null 2>&1 || echo "⚠️ Docker not found" # Set up git hooks if [ -d .git ]; then git config core.hooksPath .githooks fi echo "✅ Environment initialised successfully"
Environment Variables
Devbox allows you to define environment variables that are automatically set when entering the shell. This is useful for configuration that should be consistent across all development machines.
{
"packages": ["nodejs@20", "postgresql@15"],
"env": {
"NODE_ENV": "development",
"LOG_LEVEL": "debug",
"DATABASE_URL": "postgresql://localhost:5432/myapp_dev",
"API_BASE_URL": "http://localhost:3000",
"CACHE_TTL": "3600",
"# You can reference other variables",
"APP_NAME": "my-application",
"DATA_DIR": "$PWD/data"
}
}Sensitive Variables
Never commit sensitive values like API keys or passwords to devbox.json. Use init_hook to load them from a local .env file that's git-ignored.
Devbox Shell vs Devbox Run
Devbox provides two ways to execute commands: interactive shell and direct execution. Understanding when to use each is key to an efficient workflow.
devbox shell
Opens an interactive shell with all packages available. Best for development sessions where you'll run multiple commands.
$ devbox shelldevbox run
Executes a single command or script and exits. Best for CI/CD, automation, and one-off commands.
$ devbox run testDefining Scripts
{
"packages": ["nodejs@20", "postgresql@15"],
"shell": {
"scripts": {
"dev": "npm run dev",
"build": "npm run build",
"test": "npm test",
"test:watch": "npm test -- --watch",
"lint": "eslint . --ext .ts,.tsx",
"format": "prettier --write .",
"db:start": "pg_ctl start",
"db:stop": "pg_ctl stop",
"db:migrate": "prisma migrate dev",
"clean": "rm -rf node_modules dist .next"
}
}
}Usage Examples
# Run a defined script
devbox run dev
devbox run test
devbox run db:migrate
# Run an arbitrary command
devbox run -- npm install lodash
devbox run -- python -c "print('Hello from Devbox')"
# Chain commands
devbox run -- npm install && npm test
# Use in CI/CD
devbox run build
devbox run testDevbox Services
Devbox can manage background services like databases, message queues, and caches. Services are defined in devbox.json and managed with simple commands.
Enabling Services
{
"packages": [
"postgresql@15",
"redis@7",
"nginx"
],
"env": {
"PGDATA": "$PWD/.devbox/virtenv/postgresql/data",
"PGHOST": "$PWD/.devbox/virtenv/postgresql",
"REDIS_DATA": "$PWD/.devbox/virtenv/redis"
}
}Managing Services
# Start all services devbox services start # Start specific services devbox services start postgresql devbox services start redis # Check service status devbox services ls # Stop services devbox services stop # Restart services devbox services restart postgresql # View service logs devbox services logs postgresql
Custom Service Configuration
For services that require custom configuration, create a process-compose.yaml file:
# process-compose.yaml
version: "0.5"
processes:
web:
command: npm run dev
availability:
restart: on-failure
depends_on:
postgresql:
condition: process_healthy
worker:
command: npm run worker
availability:
restart: on-failure
depends_on:
redis:
condition: process_healthy
postgresql:
command: postgres -D $PGDATA
readiness_probe:
exec:
command: pg_isready
initial_delay_seconds: 2
period_seconds: 5
redis:
command: redis-server
readiness_probe:
exec:
command: redis-cli ping
initial_delay_seconds: 1
period_seconds: 3Devbox vs Docker vs Vagrant
Each tool serves different purposes. Understanding their trade-offs helps you choose the right tool for your needs.
| Feature | Devbox | Docker | Vagrant |
|---|---|---|---|
| Setup Time | Seconds (cached packages) | Minutes (image builds) | Minutes to hours (VM provisioning) |
| Resource Usage | Minimal (native processes) | Low-Medium (containerised) | High (full VM) |
| Reproducibility | Excellent (Nix guarantees) | Good (image layers) | Good (provisioning scripts) |
| Learning Curve | Low (simple JSON config) | Medium (Dockerfile, compose) | Medium (Vagrantfile, provisioners) |
| Host Integration | Native (no isolation) | Limited (volume mounts) | Limited (shared folders) |
| Package Availability | 100,000+ Nix packages | Depends on base image | Depends on provisioner |
When to Use Each
- Devbox: Local development, quick project setup, team environment consistency
- Docker: Production deployments, microservices, when you need process isolation
- Vagrant: Full VM requirements, testing across different operating systems
Integrating with IDEs
Devbox integrates well with popular IDEs and editors, providing a smooth development experience with the correct tools and language servers.
VS Code
Install the Devbox extension for automatic environment activation and integrated terminal support.
- 1Install "Devbox" extension from marketplace
- 2Open a project with devbox.json
- 3Extension auto-activates devbox environment
- 4Use integrated terminal with devbox shell
JetBrains IDEs
Configure JetBrains IDEs to use Devbox-managed SDKs and tools for consistent development.
- 1Run devbox shell to activate environment
- 2Note paths: which node, which python, etc.
- 3Configure SDK paths in IDE settings
- 4Set terminal to run devbox shell on startup
Neovim / Vim
Integrate with direnv for automatic environment loading when entering project directories.
- 1Install direnv and enable devbox integration
- 2Run devbox generate direnv in project
- 3Add direnv hook to shell configuration
- 4Environment loads automatically on cd
Direnv Integration
Direnv automatically loads the Devbox environment when you enter the project directory:
# Generate direnv configuration devbox generate direnv # This creates .envrc with: # eval "$(devbox generate direnv --print-envrc)" # Allow direnv for this directory direnv allow # Now the environment loads automatically on cd!
Best Practices
Follow these best practices to get the most out of Devbox in your projects and teams.
Project Configuration
- Commit devbox.json and devbox.lock to version control
- Use specific package versions for critical dependencies
- Document any required init_hook setup in README
- Keep devbox.json at the repository root for discoverability
Team Collaboration
- Ensure all team members use devbox shell for development
- Use devbox services for shared local services like databases
- Create scripts for common development tasks using devbox run
- Document IDE integration steps for your team
CI/CD Integration
- Use devbox in CI pipelines for consistent build environments
- Cache the Nix store between CI runs for faster builds
- Run tests inside devbox shell to match local behaviour
- Use devbox run for reproducible build commands
Performance
- Use devbox global for frequently used tools across projects
- Use Nix binary caches for faster package downloads
- Avoid unnecessary packages to keep environments lean
- Use shell hooks sparingly to minimise startup time
Troubleshooting
Common issues and solutions when working with Devbox.
Nix Store Disk Space Issues
Symptom: Disk space filling up, slow package installations.
Common causes:
- Old package versions not garbage collected
- Multiple projects with different package versions
- Build artifacts accumulating in store
Solution:
# Check Nix store size du -sh /nix/store # Run garbage collection nix-collect-garbage -d # Remove old generations (keeps last 7 days) nix-collect-garbage --delete-older-than 7d # Optimise store by hard-linking identical files nix-store --optimise
Shell Not Activating Properly
Symptom: Commands not found after running devbox shell, or wrong versions used.
Common causes:
- PATH not updated correctly
- Shell init scripts overriding Devbox PATH
- Conflicting shell configurations
- Nested shell sessions
Solution:
# Verify devbox shell is active echo $DEVBOX_SHELL_ENABLED # Check PATH includes Nix packages echo $PATH | tr ':' '\n' | grep nix # Use devbox run for isolated command execution devbox run -- node --version # Debug shell activation devbox shell --print-env # Clear and reinstall if needed devbox services stop && devbox rm && devbox install
Package Not Found or Version Unavailable
Error: “Package not found in nixpkgs” or version mismatch.
Common causes:
- Package name different in nixpkgs
- Specific version not available
- Package in unfree or unstable channel
Solution:
# Search for package name
devbox search nodejs
devbox search python3
# Use specific version with @
devbox add nodejs@20
devbox add python@3.11
# Search nixpkgs directly
nix-env -qaP '.*nodejs.*'
# For unfree packages, add to devbox.json
{
"nixpkgs": {
"config": {
"allowUnfree": true
}
}
}Services Not Starting
Symptom: devbox services start fails or services immediately stop.
Common causes:
- Port already in use
- Missing configuration files
- Permission issues on data directories
- Service definition errors in process-compose.yaml
Solution:
# Check service status devbox services ls # View service logs devbox services logs postgresql # Check for port conflicts lsof -i :5432 # Restart services cleanly devbox services stop devbox services start # Debug process-compose devbox services start --debug
Devbox Slow on macOS
Symptom: devbox shell takes long to start, or commands are slow.
Common causes:
- First-time package downloads
- Rosetta translation on Apple Silicon
- Large number of packages in environment
- Antivirus scanning Nix store
Solution:
# Use native ARM packages on Apple Silicon # Devbox handles this automatically, but verify: uname -m # Should show arm64 # Exclude /nix from antivirus scanning # Add /nix to your antivirus exclusion list # Pre-install packages before entering shell devbox install # Use devbox run for one-off commands (faster startup) devbox run -- npm test
Conclusion
Devbox represents a significant step forward in developer experience. By using Nix's package management whilst hiding its complexity, Devbox makes reproducible development environments accessible to everyone.
The benefits are clear:
- Instant setup: New team members can be productive in minutes, not hours.
- True reproducibility: The same environment on every machine, guaranteed by Nix.
- Low overhead: Native execution without containers or VMs means minimal resource usage.
- Simple configuration: A single JSON file defines your entire development environment.
Whether you're working on a personal project or managing development environments for a large team, Devbox provides the tools to eliminate environment inconsistencies and focus on what matters: writing great code.

