docs/faq.md
mise.toml/.tool-versions file into my project since git shows it as an untracked fileUse mise.local.toml and put that into your global gitignore file. This file should never be committed.
If you really want to use a mise.toml or .tool-versions, here are 3 ways to make git ignore these files:
mise.toml to project's .git/info/exclude. This file is local to your project so
there is no need to commit it.mise.toml to project's .gitignore file. This has the downside that you need to
commit the change to the ignore file.mise.toml to global gitignore (core.excludesFile). This will cause git to
ignore mise.toml files in all projects. You can explicitly add one to a project if needed
with git add --force mise.toml.These are aliased. For example, mise use [email protected] is the same as mise install [email protected]. This
means it is not possible to have these be different plugins.
This is for convenience so you don't need to remember which one is the "official" name. However if something with the aliasing is acting up, submit a ticket or just stick to using "node" and "go". Under the hood, when mise reads a config file or takes CLI input it will swap out "nodejs" and "golang".
mise activate do?It registers a shell hook to run mise hook-env every time the shell prompt is displayed.
mise hook-env checks the current env vars (most importantly PATH but there are others like
GOROOT or JAVA_HOME for some tools) and adds/removes/updates the ones that have changed.
For example, if you cd into a different directory that has java 18 instead of java 17
specified, just before the next prompt is displayed the shell runs: eval "$(mise hook-env)"
which will execute something like this in the current shell session:
export JAVA_HOME=$HOME/.local/share/installs/java/18
export PATH=$HOME/.local/share/installs/java/18/bin:$PATH
In reality updating PATH is a bit more complex than that because it also needs to remove java-17,
but you get the idea.
You may think that is excessive to run mise hook-env every time the prompt is displayed
and it should only run on cd, however there are plenty of
situations where it needs to run without the directory changing, for example if .tool-versions or
mise.toml was just edited in the current shell.
Because it runs on prompt display, if you attempt to use mise activate in a
non-interactive session (like a bash script), it will never call mise hook-env and in effect will
never modify PATH because it never displays a prompt. For this type of setup, you can either call
mise hook-env manually every time you wish to update PATH, or use shims
instead (preferred).
Or if you only need to use mise for certain commands, just prefix the commands with
mise x --.
For example, mise x -- npm test or mise x -- ./my_script.sh.
mise hook-env will exit early in different situations if no changes have been made. This prevents
adding latency to your shell prompt every time you run a command. You can run mise hook-env
yourself
to see what it outputs, however it is likely nothing if you're in a shell that has already been
activated.
mise activate also creates a shell function (in most shells) called mise.
This is a trick that makes it possible for mise shell
and mise deactivate to work without wrapping them in eval "$(mise shell)".
::: warning While mise runs great in WSL, native Windows is also supported, though via the use of shims until someone adds powershell support.
As you'll need to use shims, this means you won't have environment variables from mise.toml unless you run mise via
mise x or mise run—though that's actually how I use mise on my mac so
for me that's my preferred workflow anyway.
:::
Short answer: just set http_proxy and https_proxy environment variables. These should be
lowercase.
This may not work with all plugins if they are not configured to use these env vars. If you're having a proxy-related issue installing something specific you should post an issue on the plugin's repository.
e.g.: how does mise plugin install elixir know to fetch https://github.com/asdf-vm/asdf-elixir?
We maintain an index of shorthands that mise uses as a base. This is regularly updated every time that mise has a release. This repository is stored directly into the codebase in registry/.
It depends on the command. Normally, for most commands and inside of config files, "node@20" will
point to the latest installed version of node-20.x. You can find this version by running
mise latest --installed node@20 or by seeing what the ~/.local/share/mise/installs/node/20
symlink
points to:
$ ls -l ~/.local/share/mise/installs/node/20
[...] /home/jdx/.local/share/mise/installs/node/20 -> node-v20.0.0-linux-x64
There are some exceptions to this, such as the following:
mise install node@20mise latest node@20mise upgrade node@20These will use the latest available version of node-20.x. This generally makes sense because you wouldn't want to install a version that is already installed.
mise activate as described in the getting started guidemise install in a directory with an asdf .tool-versions file and mise will install the tools::: info
Note that mise does not consider ~/.tool-versions files to be a global config file like asdf does. mise uses a
~/.config/mise/config.toml file for global configuration.
:::
Here is an example script you can use to migrate your global .tool-versions file to mise:
mv ~/.tool-versions ~/.tool-versions.bak
cat ~/.tool-versions.bak | tr -s ' ' | tr ' ' '@' | xargs -n2 mise use -g
Once you are comfortable with mise, you can remove the .tool-versions.bak file and uninstall asdf
mise should be able to read/install any .tool-versions file used by asdf. Any asdf plugin
should be usable in mise. The commands in mise are slightly
different, such as mise install [email protected] vs asdf install node 20.0.0—this is done so
multiple tools can be specified at once. However, asdf-style syntax is still supported: (mise install node 20.0.0). This is the case for most commands, though the help for the command may
say that asdf-style syntax is supported. When in doubt, just try asdf syntax and see if it works—it probably does.
::: info
UPDATE (2025-01-01): mise was designed to be compatible with the asdf written in bash (<=0.15). The new asdf written in go (>=0.16)
has commands mise does not support like asdf set. mise set is an existing command that is completely different than asdf set—in mise that sets env vars.
This isn't important for usability reasons so much as making it so plugins continue to work that call asdf commands inside of the plugin code. :::
Using commands like mise use may output .tool-versions files that are not compatible with asdf,
such as using fuzzy versions. You can set --pin or MISE_PIN=1 to make mise use output asdf-compatible versions
in .tool-versions. Alternatively, you can have mise.toml and .tool-versions sitting side-by-side. mise.toml tools
will override tools defined in a .tool-versions in the same directory.
That said, in general compatibility with asdf is no longer a design goal. It's long been the case that there is no reason to prefer asdf to mise so users should migrate. While plenty of users have teams which use both in tandem, issues with such a setup are unlikely to be prioritized.
mise uses console.rs which honors the clicolors spec:
CLICOLOR != 0: ANSI colors are supported and should be used when the program isn't piped.CLICOLOR == 0: Don't output ANSI color escape codes.CLICOLOR_FORCE != 0: ANSI colors should be enabled no matter what.Providing a secure supply chain is incredibly important. mise already provides a more secure experience when compared to asdf. Security-oriented evaluations and contributions are welcome. We also urge users to look after the plugins they use, and urge plugin authors to look after the users they serve.
For more details see SECURITY.md.
usage (https://usage.jdx.dev/) is a spec and CLI for defining CLI tools.
Arguments, flags, environment variables, and config files can all be defined in a Usage spec. It can be thought of like OpenAPI (swagger) for CLIs.
usage can be installed with mise using mise use -g usage and is required to get the autocompletion working. See autocompletion.
You can leverage usage in file tasks to get auto-completion working, see file tasks arguments.
pitchfork (https://pitchfork.en.dev/) is a process manager for developers.
It handles daemon management with features like automatic restarts on failure, smart readiness checks, shell-based auto-start/stop when entering project directories, and cron-style scheduling for periodic tasks.
spawn EINVALIn VSCode, many extensions will throw an "error spawn EINVAL" due to a Node.js security fix.
The default exe shim mode should resolve this. If you're using an older mode, you can change windows_shim_mode to exe, hardlink, or symlink.
mise install and mise use?mise install downloads and installs a tool version but does not add it to any config file.
The tool won't be automatically activated in your shell unless it's already listed in a mise.toml or .tool-versions.
mise use installs the tool and adds it to mise.toml (or ~/.config/mise/config.toml with -g), so it will be activated
automatically when you enter the directory.
If you just want to pin a tool for a project, use mise use. If you want to install
a version that's already listed in config, use mise install.
::: tip
mise install node (with no version) will install the latest version if node isn't in your config.
mise install (with no arguments) installs only the tools listed in your config files.
:::
latest mean the newest remote version?It depends on context. In config files and most commands, latest resolves to the latest
installed version. This means if you have node 20.0.0 installed and node 22.0.0 is
available remotely, latest will still point to 20.0.0.
However, some commands resolve latest to the newest available (remote) version:
mise install node@latest — installs the newest available versionmise x node@latest -- node -v — uses the newest available versionmise latest node — shows the newest available versionTo upgrade to the newest available version and update your config, run:
mise upgrade node
# or to also update mise.toml:
mise upgrade --bump node
mise trust issuesmise requires you to trust config files that were not created by you. Common issues:
ignored-configs directory in your
mise state directory (default: ~/.local/state/mise/ignored-configs/)
and remove the relevant symlink to un-ignore it.mise trust pointing to the actual file path.mise trust beforehand or set
trusted_config_paths in your global settings.~/.config/mise/config.toml) should be auto-trusted. If it's not, run
mise trust ~/.config/mise/config.toml explicitly.Run mise doctor (mise dr) to see if any config files are untrusted — it will list them
under "problems".
.python-version, .node-version, etc.) work?Idiomatic version files (.python-version, .node-version, .ruby-version, etc.) are
disabled by default in mise. They are only read if you explicitly opt in per tool using
idiomatic_version_file_enable_tools:
# Enable reading .node-version files
mise settings add idiomatic_version_file_enable_tools node
If you previously enabled idiomatic files and now want to stop mise from reading them
(e.g., because uv manages .python-version), simply don't add that tool to the list.
See Idiomatic Version Files for more information.
mise activate, shims, mise exec, and mise env relate?These all do the same core thing: they set up your environment (primarily PATH) so that
mise-managed tools are available. The difference is when and how:
| Method | How it works | Best for |
|---|---|---|
mise activate | Hooks into your shell prompt, updates PATH dynamically | Interactive terminal use |
mise activate --shims | Adds the shims directory to PATH once | IDEs, simple setups (no hooks/env support) |
mise exec / mise x | Sets up env, runs a single command, then exits | Scripts, CI, one-off commands |
mise env | Prints env vars you can eval | Integrating with other tools |
mise run | Sets up env, then runs a task | Task execution |
Shims (~/.local/share/mise/shims) | Wrapper scripts that call mise on each invocation | Non-interactive shells, IDEs |
::: warning
mise activate --shims does not support hooks, env vars from [env], or watch_files.
It only puts shims on PATH. If you need those features, use mise activate (without --shims).
:::
mise exec work?mise exec (or mise x) reads your config, sets up PATH and environment variables, then
runs the command you specify after --:
# Uses whatever node version is in your mise.toml
mise x -- node script.js
# Override with a specific version (useful when it differs from config)
mise x node@22 -- node script.js
A common pattern on Discord is mise x node@20 -- node script.js when node@20 is already
in mise.toml. This works but is redundant — mise x -- node script.js is simpler when
you just want the configured version.
mise use write to?mise use writes to the nearest mise.toml in your directory hierarchy. If there's a
mise.toml in a parent directory (including ~/.config/mise/config.toml for -g), it will
update that file.
mise use node@22 # writes to nearest mise.toml (may be a parent dir!)
mise use -g node@22 # writes to ~/.config/mise/config.toml
mise use --path mise.toml node@22 # writes to a specific file
Use mise cfg to see which config files mise is reading in the current directory.
mise manages development tool versions (node, python, go, rust, etc.) and CLI utilities.
It is not a replacement for system package managers like apt, brew, or pacman.
Things mise does not do:
If a mise-installed tool needs a system library, install that library with your OS package manager first.
mise uses Calver versioning (2024.1.0).
Breaking changes will be few but when they do happen,
they will be communicated in the CLI with plenty of notice whenever possible.
Rather than have SemVer major releases to communicate change in large releases,
new functionality and changes can be opted-into with settings like experimental = true.
This way plugin authors and users can
test out new functionality immediately without waiting for a major release.
The numbers in Calver (YYYY.MM.RELEASE) simply represent the date of the release—not compatibility or how many new features were added. Each release will be small and incremental.