Configure and operate Mise for deterministic developer environments. Use when installing runtime/tool versions, defining reusable tasks, managing layered environment variables, migrating from asdf/nvm/pyenv, or debugging mise.toml behavior in CI and local shells. Keywords: mise, mise.toml, tool versions, tasks, env, asdf migration, setup automation, dev environment.
Overall
score
99%
Does it follow best practices?
Validation for skill structure
Enable automatic environment loading when entering directories:
# Add to ~/.bashrc, ~/.zshrc, etc.
eval "$(mise activate bash)" # or zsh, fishWhen you cd into a directory with mise.toml, environment variables are automatically loaded.
# Load environment in current shell
eval "$(mise env)"
# Load environment for specific shell
eval "$(mise env -s zsh)"# Run command with mise environment
mise exec -- npm start
# Short form
mise x -- node app.js
# Run task (automatically includes environment)
mise run dev# Show all mise-managed environment variables
mise env
# Show specific variable
mise env | grep NODE_ENV
# Show environment for specific directory
mise env -C /path/to/projectEnvironment variables are loaded in this order (later overrides earlier):
~/.config/mise/config.toml)mise.toml)mise.local.toml).env, .env.local)# ~/.config/mise/config.toml
[env]
EDITOR = "vim"
NODE_ENV = "development"
# project/mise.toml
[env]
NODE_ENV = "production" # Overrides global
API_URL = "https://api.example.com"
# project/mise.local.toml
[env]
API_URL = "http://localhost:3000" # Overrides project
DEBUG = "true"Result:
EDITOR = "vim" (from global)NODE_ENV = "production" (from project, overrides global)API_URL = "http://localhost:3000" (from local, overrides project)DEBUG = "true" (from local)[env]
_.file = ".env"# .env
NODE_ENV=development
API_URL=http://localhost:3000
DATABASE_URL=postgresql://localhost/myapp[env]
_.file = [
".env", # Base configuration
".env.local", # Local overrides
".env.{{ env.NODE_ENV }}" # Environment-specific
]Load order: .env → .env.local → .env.development
[env]
NODE_ENV = "development"
# This will load .env.development
_.file = ".env.{{ env.NODE_ENV }}"# Mise ignores missing files by default
# These won't error if files don't exist
[env]
_.file = [".env", ".env.local"][tools]
python = "3.11"
[env]
VIRTUAL_ENV = "{{ config_root }}/.venv"
_.path = ["{{ config_root }}/.venv/bin"]# Automatically activates venv when entering directory
cd my-project
which python # Points to .venv/bin/python[tools]
node = "20"
[env]
NODE_ENV = "development"
_.path = ["{{ config_root }}/node_modules/.bin"]cd my-project
which eslint # Points to node_modules/.bin/eslint[tools]
go = "1.21"
[env]
GOPATH = "{{ config_root }}/.go"
_.path = ["{{ config_root }}/.go/bin"][tools]
rust = "stable"
[env]
CARGO_HOME = "{{ config_root }}/.cargo"
_.path = ["{{ config_root }}/.cargo/bin"]Mise can fully replace direnv with more features:
# Old .envrc
export NODE_ENV=development
export API_URL=http://localhost:3000
PATH_add ./node_modules/.bin# mise.toml
[env]
NODE_ENV = "development"
API_URL = "http://localhost:3000"
_.path = ["./node_modules/.bin"].envrc filesmise.toml with equivalent configurationdirenv allow with automatic mise activationmise trust if needed for project config# Show all mise environment variables
mise env
# Show as export statements
mise env -s bash
# Check specific variable
mise env | grep DATABASE_URL# Show which config files are loaded
mise config ls
# Show environment from specific config
mise env -C /path/to/project# Check for syntax errors in mise.toml
mise doctor
# Validate environment configuration
mise env --json
# See which files would be loaded
mise config lsEnvironment variables are loaded lazily - only when needed:
# Fast - doesn't load environment
cd project
# Loads environment only when needed
npm start # Environment loaded hereMise caches environment calculations:
# First load - slower
cd project && mise env
# Subsequent loads - faster (cached)
cd project && mise env# Clear environment cache
mise cache clear# Enable completion for environment variables
eval "$(mise activate bash)"
# Tab completion works for mise-managed vars
echo $NODE_<TAB># ~/.config/fish/config.fish
mise activate fish | source# ~/.config/nushell/config.nu
mise activate nu[env]
NODE_ENV = "development"
_.file = ".env.{{ env.NODE_ENV }}"
# Loads .env.development in dev
# Loads .env.production in prod# In CI pipeline
mise install # Install tools
mise exec -- npm test # Run with environment# Dockerfile
FROM node:20
WORKDIR /app
# Install mise
RUN curl https://mise.run | sh
ENV PATH="/root/.local/bin:$PATH"
# Copy config and install tools
COPY mise.toml .
RUN mise install
# Use mise to run application
CMD ["mise", "exec", "--", "npm", "start"]mise activate for automatic loadingmise exec over manual env loadingmise env to verify loaded variablesmise trust for known projects# Don't mix direnv and mise
eval "$(direnv hook bash)"
eval "$(mise activate bash)"# Use mise exclusively
eval "$(mise activate bash)"# Don't override mise-managed variables
export NODE_ENV=production # Conflicts with mise[env]
NODE_ENV = "production"# Don't manually source files
source .env[env]
_.file = ".env"