The Complete Guide to Mise: Replace asdf/nvm/pyenv — Manage Dev Environments 10x Faster
TL;DR — Mise is a multi-language version manager written in Rust, over 20x faster than asdf. One tool handles version switching for Node.js, Python, Ruby, Go, Java, and 50+ other dev tools. It also includes environment variable management and a task runner.
Why Do You Need Mise?
If you're a full-stack developer, your daily life probably looks like this:
- Project A needs Node.js 18, Project B needs Node.js 20
- Backend runs on Python 3.11, but that legacy project is stuck on Python 3.9
- Every now and then you're writing Ruby, Go, or Rust
To manage all these versions, you've probably installed:
| Tool | Manages |
|---|---|
nvm |
Node.js versions |
pyenv |
Python versions |
rbenv |
Ruby versions |
gvm |
Go versions |
asdf |
Universal version manager |
The problem: each tool has its own config format, its own shell hooks, its own .tool-versions or .nvmrc files. The maintenance burden is huge. And most of these tools are written in Bash — painfully slow to start.
Mise (pronounced /miːz/, "meez") is here to end all of that.
What Is Mise?
Mise (French for "to put") is a dev tool manager written in Rust that combines the following into one:
- Multi-language version management — replaces asdf/nvm/pyenv/rbenv/gvm and more
- Environment variable management — replaces direnv
- Task runner — replaces Makefile/just/task
Key Advantages
| Feature | Mise | asdf | nvm + pyenv |
|---|---|---|---|
| Language | Rust | Bash | Bash |
| Install speed | ⚡ Blazing fast (parallel downloads) | 🐢 Slow (cloning one by one) | 🐢 Slow |
| Shell startup delay | ~0ms (no shims needed) | ~200-500ms | ~100-300ms |
.nvmrc support |
✅ | ❌ | ✅ |
.python-version support |
✅ | ❌ | ✅ |
.tool-versions (asdf) support |
✅ | ✅ | ❌ |
| Environment variable management | ✅ Built-in | ❌ | ❌ |
| Task runner | ✅ Built-in | ❌ | ❌ |
| Auto-completion | ✅ Auto-generated | ❌ Manual setup | ❌ |
GitHub stats: 30,000+ Stars, 1,200+ Forks, MIT license, actively maintained.
Installing Mise
Mise is easy to install and supports all major platforms.
Linux / macOS (Recommended)
# One-liner install
curl https://mise.run | sh
# Or via Homebrew (macOS)
brew install mise
# Or via Cargo (Rust ecosystem)
cargo install mise
Activating Shell Integration
After installation, add the activation command to your shell config:
# Bash — add to ~/.bashrc
echo 'eval "$(mise activate bash)"' >> ~/.bashrc
# Zsh — add to ~/.zshrc
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
# Fish — add to ~/.config/fish/config.fish
echo 'mise activate fish | source' >> ~/.config/fish/config.fish
Reload your shell:
source ~/.bashrc # or source ~/.zshrc
Verifying the Installation
mise --version
# Output similar to: mise 2026.x.x
mise doctor
# Checks installation status and displays all diagnostics
Quick Start: Manage Your First Tool in 5 Minutes
Installing Node.js
# Install the latest LTS version
mise use -g node@lts
# Install a specific version
mise use -g node@20
# List installed versions
mise ls node
-g means global install (writes to ~/.config/mise/config.toml). Without -g, it writes to .mise.toml in the current directory for project-level version pinning.
Installing Python
# Install Python 3.12
mise use -g python@3.12
# Verify
python --version
# Python 3.12.x
Installing Multiple Tools at Once
# Install multiple tools in one command
mise use -g node@20 python@3.12 go@1.22 ruby@3.3 rust@latest
# List all currently active tools
mise ls
Project-Level Version Pinning
Navigate to your project directory and create .mise.toml:
cd ~/projects/my-app
# Set Node.js 20 and Python 3.11 for this project
mise use node@20 python@3.11
This generates a .mise.toml file:
[tools]
node = "20"
python = "3.11"
Commit this file to Git. When teammates clone the repo, they just run mise install and all required versions are installed automatically.
Compatibility with Existing Config Files
Mise automatically recognizes these files — no extra configuration needed:
| File | Corresponding Tool |
|---|---|
.nvmrc |
Node.js |
.node-version |
Node.js |
.python-version |
Python |
.ruby-version |
Ruby |
.go-version |
Go |
.tool-versions |
asdf universal format |
.mise.toml / mise.toml |
Mise native format |
This means you can seamlessly replace asdf/nvm/pyenv without changing any existing project configuration.
Advanced Features
1. Environment Variable Management (direnv Replacement)
Mise has built-in environment variable management. It auto-loads/unloads env vars based on your current directory:
# .mise.toml
[env]
DATABASE_URL = "postgres://localhost:5432/myapp"
REDIS_URL = "redis://localhost:6379"
NODE_ENV = "development"
API_KEY = {value = "sk-test-xxx", redact = true} # Auto-redacted in logs
Supports .env files:
[env]
_.file = ".env" # Load from .env file
_.path = ["./bin", "./scripts"] # Auto-add to PATH
Difference from direnv: Mise manages env vars and tool versions in the same file — no need for two separate configs.
2. Task Runner (Makefile Replacement)
Mise includes a powerful built-in task runner:
# .mise.toml
[tasks.build]
description = "Build the project"
run = "npm run build"
[tasks.test]
description = "Run tests"
run = ["npm test", "npm run lint"]
[tasks.dev]
description = "Start dev server"
run = "npm run dev"
depends = ["build"] # Dependency: build runs first
[tasks."db:migrate"]
description = "Run database migrations"
run = "python manage.py migrate"
Usage:
# Run tasks
mise run build
mise run test
mise run dev
# List all available tasks
mise tasks
# Run with arguments
mise run build -- --watch
3. Aliases and Shortcuts
# .mise.toml
[alias.node]
lts = "20"
latest = "22"
[alias.python]
myproj = "3.11.6" # Pinned project version
4. Multi-Version Parallel and Auto-Switching
Mise's core magic is automatic version switching. When you cd into a different directory, Mise reads that directory's config and switches tool versions automatically:
# Project A needs Node 18
cd ~/projects/project-a
node --version # v18.x.x (auto-switched)
# Project B needs Node 20
cd ~/projects/project-b
node --version # v20.x.x (auto-switched)
All of this happens with zero delay — because Mise is written in Rust, there's no Bash script running on every cd like with nvm.
5. Backend System
Mise supports multiple install backends, giving you flexibility in where tools come from:
# Use official pre-built binaries (default, fastest)
[tools]
node = "20"
# Use asdf plugin ecosystem
[tools]
node = "asdf:mise-plugins/mise-node"
# Use ubi (universal binary installer)
[tools]
jq = "ubi:jqlang/jq"
# Use go install
[tools]
golangci-lint = "go:golang.org/x/tools/gopls@latest"
# Use npm global install
[tools]
typescript = "npm:typescript"
# Use pip install
[tools]
black = "pip:black"
# Use cargo install
[tools]
ripgrep = "cargo:ripgrep"
This means Mise doesn't just manage language runtimes — it manages any dev tool: linters, formatters, CLI utilities, and more.
Real-World Example: Setting Up a Full-Stack Dev Environment with Mise
Let's build a typical full-stack project (Next.js frontend + FastAPI backend) dev environment from scratch using Mise.
Step 1: Create Project Structure
mkdir ~/projects/fullstack-app && cd ~/projects/fullstack-app
mkdir frontend backend
Step 2: Root Directory Config
Create mise.toml in the project root:
# mise.toml
[tools]
node = "20" # Frontend needs this
python = "3.12" # Backend needs this
[env]
_.file = ".env" # Global environment variables
[tasks.setup]
description = "Initialize the entire project"
run = [
"cd frontend && npm install",
"cd backend && pip install -r requirements.txt"
]
[tasks.dev]
description = "Start all services"
run = [
"cd frontend && npm run dev &",
"cd backend && uvicorn main:app --reload"
]
Step 3: One-Command Initialization
# Install all tools
cd ~/projects/fullstack-app
mise install
# Run the setup task
mise run setup
# Start the dev environment
mise run dev
Your entire team just needs git clone + mise install + mise run dev to get the dev environment running. No more "but it works on my machine" problems.
Step 4: CI/CD Integration
Use Mise directly in GitHub Actions:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install mise
uses: jdx/mise-action@v2
- name: Install tools
run: mise install
- name: Frontend tests
run: cd frontend && npm test
- name: Backend tests
run: cd backend && pytest
mise-action reads mise.toml automatically and installs all required tools. No need to manually configure actions/setup-node, actions/setup-python, etc.
Migrating from asdf to Mise
If you're already an asdf user, migration is straightforward:
# Mise is fully compatible with .tool-versions files
# You don't even need to do anything — Mise reads them automatically
# But if you want to convert .tool-versions to mise.toml:
mise migrate asdf
# Remove asdf after migration (optional)
# Bash
sed -i '/asdf.sh/d' ~/.bashrc
# Zsh
sed -i '/asdf.sh/d' ~/.zshrc
Key advantages:
- mise install is 20x+ faster than asdf install (parallel downloads + pre-built binaries)
- No shim layer — zero shell startup delay
- Better error messages and auto-completion
- Built-in task runner and environment variable management
Mise vs. Other Tools — Summary
| Scenario | Traditional Approach | Mise Approach |
|---|---|---|
| Managing 3 language versions | Install 3 tools | 1 tool |
| Team environment consistency | Everyone installs manually | mise install — one command |
| Shell startup speed | ~300ms+ | ~0ms |
| Environment variables | direnv / manual export | Built-in |
| Project tasks | Makefile / package.json scripts | Built-in tasks |
| CI configuration | One action per language | One mise-action |
Conclusion
Mise is one of the most practical developer tools I've come across in recent years. It leverages Rust's raw performance to solve the pain points of version management, replacing the scattered collection of nvm, pyenv, rbenv, direnv, and Makefile with a single unified tool.
Why it's worth using:
- ⚡ Fast — Written in Rust, 20x faster than asdf
- 🔧 Unified — One tool to manage all your dev tool versions
- 🔄 Compatible — Fully compatible with
.nvmrc,.tool-versions, and other existing configs - 🚀 Ecosystem — Supports 50+ languages and tools
- 📦 Built-in task runner — No extra Makefile needed
- 🌍 Environment variable management — No extra direnv needed
- 🤝 Team collaboration — Commit
mise.tomlto Git; new members get set up with one command
Useful links:
- GitHub: jdx/mise
- Docs: mise.jdx.dev
- Plugin ecosystem: Mise official plugin list
If you're still running the nvm + pyenv + asdf combo, give Mise a serious try. You'll wonder how you ever managed without it.