Skip to content

Dev tools ​

mise installs tools such as Node.js, Python, and Go, and selects their versions for each project. Declare the versions a project uses in mise.toml, and mise puts them on PATH while you work in that directory.

Add a tool to a project ​

From the project directory:

sh
mise use node@24 python@3.14

This installs both tools and records the version requests in the project's config:

mise.toml
toml
[tools]
node = "24"
python = "3.14"

Run a command with those tools:

sh
mise exec -- node --version
# v24.x.x

With shell activation, you can run node --version directly, and mise switches versions as you move between projects. After you clone a repository or edit its mise.toml, run mise install to install the tools it declares.

Everyday commands ​

GoalCommand
Add or change a project's tool versionmise use node@24
Set a personal defaultmise use --global node@24
Install the tools a project declaresmise install
Also install the tools its tasks needmise install --include-task-tools
Run a version once without saving itmise exec node@24 -- node --version
Show the tools this directory usesmise ls --current
List the versions you can installmise ls-remote node
Show which executable a command runsmise which node
Show tools with newer versionsmise outdated
Upgrade within the configured requestmise upgrade node
Upgrade and rewrite the requestmise upgrade --bump node
Remove a tool from the projectmise unuse node
Delete an installed versionmise uninstall node@22

mise use installs a version and writes the request to the project's mise.toml. Add --pin to write the resolved version instead, --global to write a personal default to ~/.config/mise/config.toml, or --path to choose the file; see which file mise writes to. mise use cannot change the shell it runs in: activation applies the change at the next prompt, and mise exec and tasks read it each time.

mise install installs tools without changing any config:

  • mise install node@24.11.1 installs that version.
  • mise install node@24 installs the newest 24.x release.
  • mise install node installs the version the config selects.
  • mise install installs every configured tool except tools marked lazy = true; add --include-lazy to install those too.
  • mise install --include-task-tools also installs the tools that tasks in the current scope need, without running them, which warms CI, container, or offline caches. Add --monorepo to include every configured monorepo root.

mise exec reads the same config files, so without activation or shims you can prefix any command with mise exec --. An alias such as alias mx='mise exec --' saves typing. mise run loads the same tools and environment for tasks.

How mise selects a tool ​

  1. mise reads mise.toml and other config files from the current directory, its parents, and your global config. A file closer to the current directory overrides one further up; see config file locations.
  2. The registry maps a short name such as node to a backend, which lists versions and installs the tool.
  3. The backend resolves the version request, such as 24 or latest. mise reuses an installed version that matches before it looks for a newer one, and a lockfile can fix the result.
  4. mise puts the selected tools on PATH for the command, task, or shell. mise exec and mise run install missing tools first.

mise also reads .tool-versions files. Version files from other tools, such as .nvmrc and .python-version, need idiomatic version files turned on. If you are coming from asdf, see Migrating from asdf. Run mise config ls to see which config files apply in a directory.

Shells, editors, and scripts ​

  • In an interactive shell, activate mise so PATH and project environment variables update at each prompt.
  • In editors and IDEs, use shims or an editor integration where a program needs a stable executable path.
  • In scripts and CI, run mise exec -- <command> or mise run <task>; see Continuous integration.

Shims compares the three approaches.

Upgrade tools ​

mise outdated lists configured tools with a newer release that matches their request. Add --bump to compare against the newest release overall.

mise upgrade installs the newest release within each request. With node = "24" in mise.toml, mise upgrade node installs the newest 24.x and leaves mise.toml alone. When the project uses a lockfile, mise updates mise.lock to the new version.

--bump upgrades to the newest release and rewrites the request with the same precision: node = "24" becomes node = "26", and node = "24.11.1" becomes the newest exact version. When you name a request, as in mise upgrade --bump node@latest, mise writes that request instead.

sh
mise upgrade --dry-run      # show what would change
mise upgrade --interactive  # pick tools from a list
mise upgrade --bump --local # bump only tools in project config

After an upgrade, mise schedules the version it replaced for removal once upgrade.prune_after has passed, so running programs can keep using it. Pass --prune to remove it now, or --no-prune to keep it; set upgrade.auto_prune to false to keep replaced versions by default.

Automatic tool updates ​

A tool in your global config (~/.config/mise/config.toml) can keep itself up to date. Set auto_update on its entry:

~/.config/mise/config.toml
toml
[tools]
claude = { version = "latest", auto_update = true }
node = { version = "24", auto_update = "6h" }

When a shim or mise exec is about to run the tool and mise has not checked for an update within the interval, it runs mise upgrade for that tool first, showing the usual install progress, then runs the new version. Updates stay within the request: node = "24" gets the newest 24.x, never 26. If the update fails or you are offline, mise warns and runs the version you have.

auto_update = true checks every tool_update.check_duration. A duration such as "6h" sets that tool's own interval. Intervals under one hour are raised to one hour.

  • Only global config can turn this on. A project config cannot, and when a project sets its own version of the tool, runs in that project do not update it.
  • Only the tool being run is checked: mise exec -- npm test does not update claude. Tasks, mise hook-env, and shell activation never update tools.
  • Exact versions such as node = "24.11.1" are never updated. If a global lockfile (mise lock --global) pins the tool, the update moves the lock entry to the new version. A project's config and lockfile are never changed.
  • No updates run offline, in CI, or with locked = true.
  • The previous version is pruned on the same schedule as after mise upgrade.
  • If the last update of a tool failed, mise doctor shows the error.

To update in the background instead, so launches never wait and tools run directly from PATH with shell activation stay current too, declare the tool-update service in your global config and run mise bootstrap services apply:

~/.config/mise/config.toml
toml
[bootstrap.services.mise-tool-update]
builtin = "tool-update"

The service checks once an hour and updates each tool when its interval is due. While it runs, launches do not update tools themselves. See user services.

Remove tools ​

CommandEdits configDeletes installed versions
mise unuse nodeRemoves the requestVersions that no tracked config or tool stub still needs
mise uninstall node@22NoThat version; --all deletes every version of the tool
mise pruneNoEvery version that no tracked config or tool stub still needs

mise unuse edits the first loaded config that declares the tool, or the file you pick with --path, --global, or --env. A version argument matches the request as written, so node = "24" is removed with mise unuse node@24, not with the resolved version. Add --no-prune to keep the installations.

mise uninstall deletes installations and leaves config alone, so a tool that is still configured installs again on the next mise install.

mise prune deletes versions that no config file mise has used, and no tool stub that has run, still needs. mise records those files in ~/.local/state/mise/tracked-configs and tracked-stubs. It keeps versions that a running process started from. Run mise ls --prunable or mise prune --dry-run to see what it would delete.

Automatic installation ​

When a configured tool is missing, mise can install it instead of failing. Setting auto_install to false turns off the first four cases below, and auto_install_disable_tools lists tools they skip. A lazy tool still installs on first use.

When you runmise installsControlled by
mise execMissing tools the config selectsexec_auto_install
mise runMissing tools the task needstask.run_auto_install
An unknown command in an activated shell, or a shim for a missing versionThe configured tool that provides the commandnot_found_auto_install
An unknown command that no config mentionsThe one registry tool that provides it, added to global confignot_found_auto_install_registry, off by default
A command of a lazy toolThat tool, on first uselazy = true on the tool

With auto-install off, mise exec warns that the tool is missing and runs whatever copy of the command is on PATH. The command-not-found handler finds tools through the registry's command names, so it cannot install a tool declared with a raw backend such as cargo:some-crate until a version of it is installed; see troubleshooting.

Tool options ​

Write a tool as a table instead of a version string to set options. The options below work with any tool entry, except where a row names the backends that support them. Backend-specific options, such as matching for GitHub, are listed on each backend page.

OptionWhat it does
versionThe version request. Use prefix, ref, or path instead for those kinds of request.
osInstall and use the tool only on these platforms; see OS-specific tools.
dependsInstall these tools first; see Tool dependencies.
install_envEnvironment variables for the commands that install the tool (build scripts, package managers, plugin hooks) and for its postinstall. mise also reads GitHub, GitLab, and Forgejo token variables from it when it resolves and downloads the tool; see tokens.
postinstallA command to run after the tool installs; see Tool postinstall commands.
lazy, lazy_binsInstall the tool the first time one of its commands runs; see Lazy tools.
auto_updateIn global config only, update the tool before it runs; see Automatic tool updates.
minimum_release_ageSelect only versions released at least this long ago, where the backend reports release dates; see minimum release age.
prereleaseInclude prereleases in mise ls-remote and when resolving latest or a prefix. Every backend honors it except the core java plugin; see prereleases.
version_orderOrder versions by semver or by source on aqua, github, gitlab, forgejo, and http tools; see Version ordering.

mise's HTTP client does not read proxy variables from install_env, so set HTTPS_PROXY and similar variables in the environment that starts mise.

Inline or table syntax ​

Short options fit on one line; use a table when a tool has several. These are equivalent:

toml
[tools]
ripgrep = { version = "15", os = ["linux", "macos"] }
toml
[tools.ripgrep]
version = "15"
os = ["linux", "macos"]

mise reads TOML 1.1, so an inline table can span several lines and end with a trailing comma. Nested options, such as the HTTP backend's per-platform platforms, can use dotted keys or one line per platform:

mise.toml
toml
[tools."http:my-tool"]
version = "1.0.0"
platforms.macos-arm64.url = "https://example.com/my-tool-macos-arm64.tar.gz"
platforms.linux-x64.url = "https://example.com/my-tool-linux-x64.tar.gz"

See the HTTP backend for checksums and executable selection.

Options on the command line ​

Append options in brackets to the tool name, separated by commas, before the version. Quote the argument so the shell does not expand the brackets:

sh
mise use 'github:jqlang/jq[version_prefix=jq-,rename_exe=jq]@1.8.2'

The same form works with mise install and mise exec. mise use writes the options to mise.toml:

mise.toml
toml
[tools]
"github:jqlang/jq" = { version = "1.8.2", version_prefix = "jq-", rename_exe = "jq" }

mise use --tool-option KEY=VALUE sets an option for the tool that follows it. mise use --tool-option mr_boxington=true rust mr-boxington sets the option on rust and adds the mr-boxington tool, which the option needs; see Cache Cargo builds with Mr Boxington.

Variables in tool options ​

Versions and option values can use templates with environment variables and vars, including values that [env] loads with _.source, _.file, or environment modules. For example, point a Go install at your company's module proxy:

mise.toml
toml
[vars]
goproxy = "https://goproxy.example.com"

[tools]
go = "1.27"
"go:github.com/mikefarah/yq/v4" = { version = "latest", install_env = { GOPROXY = "{{ vars.goproxy }}" } }

OS-specific tools ​

Set os to install and use a tool only on some platforms. Everywhere else, mise skips the tool:

mise.toml
toml
[tools]
# Linux and macOS only
ripgrep = { version = "latest", os = ["linux", "macos"] }

# Windows only
"github:PowerShell/PowerShell" = { version = "latest", os = ["windows"] }

# Linux, and macOS on Apple silicon
hk = { version = "latest", os = ["linux", "macos/arm64"] }

Values are linux, macos (or darwin), windows (or win), and unix (every platform except Windows). Add an architecture to narrow a value, as in macos/arm64 or linux/x64; architectures are arm64 (or aarch64) and x64 (or x86_64, amd64). A value without an architecture matches every architecture on that platform.

Tool dependencies ​

depends makes one tool wait for others to finish installing. Use it when a tool's install or postinstall runs another tool that its backend does not already require:

mise.toml
toml
[tools]
node = "24"
# postinstall runs npm, so node must finish installing first
# (github:example/acme is a placeholder)
"github:example/acme" = { version = "1.2.3", depends = ["node"], postinstall = "npm install --prefix ~/.acme acme-plugins" }

depends takes one tool name or a list. It only orders installation; it does not add or install the listed tools. Each one must be in [tools], where it installs first, or already be on PATH. While the dependent tool installs and runs its postinstall, the listed tools are on PATH. Plugin authors declare a plugin's own requirements with PLUGIN.depends; see Tool plugin development.

Tool postinstall commands ​

postinstall runs a command after this tool installs. It is separate from the [hooks].postinstall hook, which runs once after a whole mise install:

mise.toml
toml
[tools]
node = { version = "24", postinstall = "corepack enable" }

By default the command runs only when mise installs or repairs the tool, never after a failed install, and never with --dry-run. To run it on every mise install and mise use, even when the version is already installed, set when = "always":

mise.toml
toml
[tools]
node = { version = "24", postinstall = { run = "corepack enable", when = "always" } }

The command runs with the tool's bin directory and any dependencies on PATH, the tool's install_env, and the project's [env] values. Templates such as {{ tools.ripgrep.path }} are rendered first. It also receives:

  • MISE_TOOL_NAME: the tool's short name, such as node.
  • MISE_TOOL_VERSION: the version that was installed, such as 24.11.1.
  • MISE_TOOL_INSTALL_PATH: the directory the tool was installed to.
  • MISE_CONFIG_FILE: the config file that declared the tool.
  • MISE_CONFIG_ROOT: that file's config root.
  • MISE_PROJECT_ROOT: the active project root, or the config root when no project is active.

A failing postinstall fails the install.

System installations ​

mise install --system installs a tool into a shared directory, /usr/local/share/mise/installs by default, so every user account on the machine can use one copy. Run it as your normal user; on Unix, mise calls sudo only to write into the protected directory. See System installs for supported backends, directories, and sudo settings.

Caching ​

mise reuses a tool's list of remote versions for the period set by fetch_remote_versions_cache; run mise cache clear <tool> to refresh it. See Caches, and slow shell prompts if activation feels slow.

MIT LicenseCopyright © 2026jdx.dev