Working across large repositories that mix multiple technologies is common in modern software teams. Keeping everyone aligned on the same tool versions, environment variables, and runtimes has always been a friction point — until I started using Mise (mise-en-place).

It has since replaced several tools on my machine (goodbye nvm, reduced Homebrew usage) and become my go-to for managing development environments, both locally and in CI.

Getting Started

Installation is straightforward — the official guide is short and clear.

Once installed, drop a mise.toml at the root of your project and declare the tools you need:

[tools]
node    = "24"
python  = "3.13.2"
rust    = "1.90.0"
helm    = "3.19.0"
java    = "24"
maven   = "3.9.5"
dotnet  = "9"
pnpm    = "10"

Then run:

mise install

That’s it. All declared tools are installed and ready.


Automatic Version Switching

One of Mise’s best features is automatic tool switching when you navigate between directories. Each project can declare its own versions in a local mise.toml, and Mise activates the right set the moment you cd in.

Enable it in your shell:

# Bash
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc

# Zsh
echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc

After that, version management becomes invisible — no manual use commands, no version conflicts between projects.


Global Tools

You can also install tools globally, outside any specific project:

mise use -g node@22
mise use --global npm:@anthropic-ai/claude-code

Global configuration is stored in ~/.config/mise/config.toml. Mise always resolves the closest config first (local project, then global), so your global defaults never interfere with project-specific requirements.


Managing Environment Variables

Mise can manage environment variables alongside your tools, which makes it handy for local secrets and per-project configuration. Create a mise.local.toml file (added to .gitignore) with your local values:

[env]
DATABASE_URL = "postgres://user:pass@localhost/dbname"
API_KEY      = "your-secret-key-here"
AWS_REGION   = "eu-west-1"

This file can also override the [tools] section if you need local overrides without touching the shared config.


Cleaner CI/CD Pipelines

Polyglot CI pipelines are notoriously messy. Common approaches each come with trade-offs:

  • One giant image with all runtimes → slow, heavy, hard to maintain
  • Multiple images per stack → complex pipeline matrix management
  • Manual tool installation scripts → brittle, hard to keep in sync with local dev

With Mise, the pipeline just needs to install Mise itself, then run mise install. Everything declared in mise.toml is installed in a predictable location, which also makes caching straightforward.

For GitHub Actions, a ready-made action is available:

- name: Setup mise
  uses: jdx/mise-action@v3
  with:
    install: true
    cache: true
    experimental: true

Nix Integration

If your team uses Nix, Mise has a plugin by José Badeau that lets you declare Nix packages with the same syntax as any other tool:

mise plugin install nix https://github.com/jbadeau/mise-nix.git
[tools]
"nix:nodejs_22" = "latest"
"nix:pnpm"      = "latest"
"nix:zulu"      = "latest"
"nix:maven3"    = "latest"

Same developer experience, Nix under the hood.


Summary

Mise centralizes your entire development toolchain in a single mise.toml file — runtimes, tool versions, and environment variables — and makes it reproducible across machines and CI environments. It eliminates the need for version managers like nvm or pyenv, simplifies CI pipelines, and integrates naturally with ecosystems like Nix and Nx.

If you work in polyglot environments or just want a cleaner, more consistent local setup, Mise is worth a serious look.