mise
Polyglot runtime manager and task runner
mise is an open-source development tool that manages programming language runtimes, environment variables, and project tasks. It replaces multiple version managers with a single self-contained binary.
Key features
- Multi-language version manager
- Built-in task runner
- Environment management
- asdf plugin compatible
Pros & cons
Strengths
- Single fast binary
- Replaces many version managers
- Compatible with asdf plugins
Trade-offs
- Shell integration required
- Rapid release pace
mise replaces
Last reviewed Aug 26, 2026 · 708 words
Put one file in the root of your homelab repo and every machine you clone it to gets the same Node, Python, and Go versions the moment you cd in:
# mise.toml
[tools]
node = "22"
python = "3.12"
go = "latest"
[tasks.up]
run = "docker compose up -d --remove-orphans"
[tasks.backup]
run = "restic backup /srv --tag nightly"
That is mise: a single Rust binary that replaces nvm, pyenv, rbenv, and asdf at once, reads the same .tool-versions files asdf did, and adds a task runner and per-directory environment variables. For the self-hoster it is less a development tool than a way to make the scripting environment on 3 machines identical.
Install is one line and one shell hook
curl https://mise.run | sh
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc
The activate hook is the part the "shell integration required" complaint is about. It runs on every prompt, checks whether the directory has a mise.toml or .tool-versions, and adjusts PATH accordingly. It is fast enough that I cannot measure it, and there is a mise x (exec) form for scripts and cron jobs that do not have an interactive shell: mise x -- python backup.py runs with the pinned interpreter without any hook. That form matters on a server, because cron does not source your .bashrc. Zsh and fish work the same way with their own activate lines. Versions install on demand: mise install in a project fetches whatever the file lists, and mise use node@22 writes the pin for you.
It reads asdf plugins, so nothing you had is lost
Most languages are built in: mise fetches official binaries or prebuilt archives through its core tooling and registries such as GitHub releases, which is why it is much faster than asdf's shell-script plugins. For anything not covered, mise plugin add pulls the same plugin repositories asdf used, and .tool-versions files are honoured as-is. That backward compatibility is what made it safe to switch a whole team over in an afternoon, and it is why the project reached 33,032 GitHub stars only 3 years after its 2023 release.
Tasks replace the pile of shell scripts in every homelab repo
Every self-hosting repo I have seen grows a scripts/ directory and a README listing the invocations. mise run up, mise run backup, and mise tasks to list them, with dependencies (depends = ["build"]), file-based tasks in a mise-tasks/ directory, and environment variables from the [env] block, cover the same ground with less. Combined with the Docker Compose homelab patterns I describe elsewhere, a fresh machine goes from clone to running stack in mise install && mise run up. Secrets belong in mise.local.toml, which is gitignored by convention, or in a .env file the [env] block can load with _.file = ".env".
Where mise does not belong
Inside container images. A Dockerfile should install the exact runtime it needs from an official base image, not run a version manager at build time; mise adds a layer, a network fetch, and a moving target. Likewise on a server nobody shells into, a system package or a pinned binary is simpler than a hook. mise's home is the workstation, the CI runner, and the one homelab box where you actually run scripts by hand. The other caveat is release cadence: the project ships very frequently. Pin the version you install (mise self-update exists, but so does not running it) and read the changelog when something changes shape, which is the price of a tool that is still improving fast. The official docs are excellent and worth an hour before you commit.
What I'd do
Install it on your workstation and on the one server you administer interactively, commit a mise.toml to your homelab repo with the runtimes pinned and 4 or 5 tasks defined, and delete nvm and pyenv the same day. Keep runtimes in Dockerfiles for anything containerised. Among the dev tools I recommend, it is the one with the best ratio of setup time to daily annoyance removed, and the MIT license means there is no catch.
Compare mise
1 head-to-head comparisons.
Similar developer tools & git apps
Excalidraw
Developer Tools & GitVirtual hand-drawn style whiteboard
Replaces Miro
lazygit
Developer Tools & GitSimple terminal UI for Git commands
Replaces GitKraken, Sourcetree
Hoppscotch
Developer Tools & GitOpen-source API development ecosystem
Replaces Postman, Insomnia
json-server
Developer Tools & GitFull fake REST API from a JSON file in seconds
Replaces Mockoon, Postman Mock
Strapi
Developer Tools & GitLeading open-source headless CMS
Replaces Contentful
NocoDB
Developer Tools & GitOpen-source Airtable alternative
Replaces Airtable