docs/configuration.md
Learn how to configure mise for your project with mise.toml files, environment variables, and various configuration options to manage your development environment.
mise.tomlmise.toml is the config file for mise. They can be at any of the following file paths (in order of precedence, top overrides configuration of lower paths):
mise.local.toml - used for local config, this should not be committed to source controlmise.tomlmise/config.toml.mise/config.toml.config/mise.toml - use this in order to group config files into a common directory.config/mise/config.toml.config/mise/conf.d/*.toml - all files in this directory will be loaded in alphabetical order::: tip
Run mise cfg to figure out what order mise is loading files on your particular setup. This is often
a lot easier than figuring out mise's rules.
:::
Notes:
mise can be dotfiles, e.g.: .mise.toml or .mise/config.toml.mise.development.toml—set with MISE_ENV=development.LOCAL_CONFIG_FILENAMES in src/config/mod.rs for the actual code for these paths and their precedence. Some legacy paths are not listed here for brevity.mise uses a sophisticated hierarchical configuration system that merges settings from multiple sources. Understanding this hierarchy helps you organize your development environments effectively.
These files recurse upwards, so if you have a ~/src/work/myproj/mise.toml file, what is defined
there will override anything set in
~/src/work/mise.toml or ~/.config/mise.toml. The config contents are merged together.
When mise needs configuration, it follows this process:
MISE_CEILING_PATHS)mise.dev.toml if MISE_ENV is set/
├── etc/mise/ # System-wide config (highest precedence)
│ ├── conf.d/*.toml # System fragments, loaded alphabetically
│ ├── config.toml # System defaults
│ └── config.<env>.toml # Env-specific system config (MISE_ENV or -E)
└── home/user/
├── .config/mise/
│ ├── conf.d/*.toml # User fragments, loaded alphabetically
│ ├── config.toml # Global user config
│ ├── config.<env>.toml # Env-specific user config
│ ├── config.local.toml # User-local overrides
│ └── config.<env>.local.toml # Env-specific user-local overrides
└── work/
├── mise.toml # Work-wide settings
└── myproject/
├── mise.local.toml # Local overrides (git-ignored)
├── mise.toml # Project config
├── mise.<env>.toml # Env-specific project config
├── mise.<env>.local.toml # Env-specific project local overrides
└── backend/
└── mise.toml # Service-specific config (lowest precedence)
Different configuration sections merge in different ways:
Tools ([tools]): Additive with overrides
# Global: node@18, [email protected]
# Project: node@20, [email protected]
# Result: node@20, [email protected], [email protected]
Environment Variables ([env]): Additive with overrides
# Global: NODE_ENV=development
# Project: NODE_ENV=production, API_URL=localhost
# Result: NODE_ENV=production, API_URL=localhost
Tasks ([tasks]): Completely replaced per task
# Global: [tasks.test] = "npm test"
# Project: [tasks.test] = "yarn test"
# Result: "yarn test" (completely replaces global)
Settings ([settings]): Additive with overrides
# Global: experimental = true
# Project: jobs = 4
# Result: experimental = true, jobs = 4
::: tip
Run mise config to see what files mise has loaded in order of precedence.
:::
When commands like mise use, mise set, or mise unuse need to write to a config file, they use the lowest precedence file in the highest precedence directory. This means:
mise.toml and mise.local.toml exist, writes go to mise.tomlmise.toml and mise.production.toml exist, writes go to mise.tomlmise.local.toml exists, writes go to mise.local.tomlThis behavior ensures that shared configuration (mise.toml) is updated by default, while local overrides (mise.local.toml) and environment-specific configs remain untouched unless explicitly targeted.
::: info Example
# With both mise.toml and mise.local.toml present:
$ mise use node@22 # writes to mise.toml
$ mise use --env local node@20 # writes to mise.local.toml
$ mise set NODE_ENV=production # writes to mise.toml
:::
Here is what a typical mise.toml looks like:
[tools]
node = '24'
python = '3.12'
[env]
NODE_ENV = 'development'
[tasks.dev]
run = 'npm run dev'
[tasks.test]
run = 'pytest'
mise.toml files are hierarchical. The configuration in a file in the current directory will
override conflicting configuration in parent directories. For example, if ~/src/myproj/mise.toml
defines the following:
[tools]
node = '20'
python = '3.10'
And ~/src/myproj/backend/mise.toml defines:
[tools]
node = '18'
ruby = '3.1'
Then when inside of ~/src/myproj/backend, node will be 18, python will be 3.10, and ruby
will be 3.1. You can check the active versions with mise ls --current.
You can also have environment specific config files like .mise.production.toml, see
Configuration Environments for more details.
[tools] - Dev toolsSee Tools. In addition to specifying versions, each tool entry can include options such as:
os: Restrict installation to certain operating systemsdepends: Install order relative to other tools in this config only; vfox plugin hook dependencies belong in plugin metadata.lua (see Tool Dependencies)install_env: Environment vars used during installpostinstall: Command to run after installation completes for that specific toolExamples:
[tools]
node = { version = "22", postinstall = "corepack enable" }
[env] - Arbitrary Environment VariablesSee environments.
[tasks.*] - Run files or shell scriptsSee Tasks.
[settings] - Mise SettingsSee Settings for the full list of settings.
[plugins] - Specify Custom Plugin Repository URLsUse [plugins] to add/modify plugin shortnames. Note that this will only modify
new plugin installations. Existing plugins can use any URL.
[plugins]
elixir = "https://github.com/my-org/mise-elixir.git"
node = "https://github.com/my-org/mise-node.git#DEADBEEF" # supports specific gitref
"vfox-backend:myplugin" = "https://github.com/jdx/vfox-npm"
The plugin type prefix (e.g., asdf:, vfox: or vfox-backend:) is optional.
If omitted, mise clones the plugin first and then detects the plugin type from
the installed plugin files.
If you simply want to install a plugin from a specific URL once, it's better to use
mise plugin install <NAME> <GIT_URL>. Add this section to mise.toml if you want
to share the plugin location/revision with other developers in your project.
This replaces the deprecated settings.shorthands_file / MISE_SHORTHANDS_FILE mechanism: put the
same shortname = "backend-or-url" entries under [plugins] instead of a separate TOML file.
[tool_alias] - Tool version aliases::: tip
[alias] has been renamed to [tool_alias] to distinguish it from [shell_alias].
The old [alias] key still works but is deprecated.
:::
The following makes mise install node@my_custom_node install node-20.x
this can also be specified in a plugin.
note adding an alias will also add a symlink, in this case:
~/.local/share/mise/installs/node/20 -> ./20.x.x
[tool_alias.node.versions]
my_custom_node = '20'
[shell_alias] - Shell aliasesDefine shell aliases that are set when entering a directory and unset when leaving:
[shell_alias]
ll = "ls -la"
gs = "git status"
dev = "npm run dev"
These work similar to environment variables—they're set dynamically based on your current directory. See Shell Aliases for more details.
Specify the minimum supported version of mise required for the configuration file.
You can set a hard minimum (errors if unmet) or a soft minimum (warns and continues):
# (equivalent to hard)
min_version = '2024.11.1'
# new object form
min_version = { hard = '2024.11.1' }
# soft recommendation
min_version = { soft = '2024.11.1' }
# both
min_version = { hard = '2024.11.1', soft = '2024.9.0' }
When a soft minimum is not met, mise will print a warning and (if available) show self-update instructions. When a hard minimum is not met, mise errors and shows self-update instructions.
Mark a configuration file as a monorepo root to enable target path syntax for tasks. Requires MISE_EXPERIMENTAL=1.
experimental_monorepo_root = true
When enabled:
//projects/frontend:build)mise tasks ls --all)See Monorepo Tasks for detailed usage and examples.
mise.toml schemamise.toml in schema/mise.json or at https://mise.en.dev/schema/mise.json.mise.toml file (VSCode, IntelliJ, neovim, etc.). It is also available in the JSON schema store.included tasks (see task configuration, there is another schema: https://mise.en.dev/schema/mise-task.json)~/.config/mise/config.tomlmise can be configured in ~/.config/mise/config.toml. It's like local mise.toml files except
that
it is used for all directories.
[tools]
# global tool versions go here
# you can set these with `mise use -g`
node = 'lts'
python = ['3.10', '3.11']
[settings]
# tools can read the versions files used by other version managers
# for example, .nvmrc in the case of node's nvm
idiomatic_version_file_enable_tools = ['node']
# keep downloaded archive/source files for debugging
always_keep_download = false # deleted after install; not a cache
always_keep_install = false # deleted on failure by default
# configure how frequently (in minutes) to fetch updated plugin repository changes
# this is updated whenever a new runtime is installed
# (note: this isn't currently implemented but there are plans to add it: https://github.com/jdx/mise/discussions/6735)
plugin_autoupdate_last_check_duration = '1 week' # set to 0 to disable updates
# config files with these prefixes will be trusted by default
trusted_config_paths = [
'~/work/my-trusted-projects',
]
verbose = false # set to true to see full installation output, see `MISE_VERBOSE`
http_timeout = "30s" # set the timeout for http requests as duration string, see `MISE_HTTP_TIMEOUT`
jobs = 4 # number of plugins or runtimes to install in parallel. The default is `4`.
raw = false # set to true to directly pipe plugins to stdin/stdout/stderr
yes = false # set to true to automatically answer yes to all prompts
not_found_auto_install = true # see MISE_NOT_FOUND_AUTO_INSTALL
task.output = "prefix" # see Tasks Runner for more information
paranoid = false # see MISE_PARANOID
# shorthands_file is deprecated - use [plugins] in this file (see "plugins" above)
disable_default_registry = false # disable the default registry, see `MISE_DISABLE_DEFAULT_REGISTRY`
disable_tools = ['node'] # disable specific tools, generally used to turn off core tools
env_file = '.env' # load env vars from a dotenv file, see `MISE_ENV_FILE`
experimental = true # enable experimental features
# configure messages displayed when entering directories with config files
status = {
missing_tools = "if_other_versions_installed",
show_env = false,
show_tools = false,
}
# "_" is a special key for information you'd like to put into mise.toml that mise will never parse
[_]
foo = "bar"
/etc/mise/config.tomlSimilar to ~/.config/mise/config.toml but for all users on the system. This is useful for
setting defaults for all users.
.tool-versionsThe .tool-versions file is asdf's config file and it can be used in mise just like mise.toml.
It isn't as flexible so it's recommended to use mise.toml instead. It can be useful if you
already have a lot of .tool-versions files or work on a team that uses asdf.
Here is an example with all the supported syntax:
node 20.0.0 # comments are allowed
ruby 3 # can be fuzzy version
shellcheck latest # also supports "latest"
jq 1.6
erlang ref:master # compile from vcs ref
go prefix:1.19 # uses the latest 1.19.x version—needed in case "1.19" is an exact match
shfmt path:./shfmt # use a custom runtime
node lts # use lts version of node (not supported by all plugins)
node sub-2:lts # install 2 versions behind the latest lts (e.g.: 18 if lts is 20)
python sub-0.1:latest # install python-3.10 if the latest is 3.11
See the asdf docs for more info on this file format.
Both mise.toml and .tool-versions support "scopes" which modify the behavior of the version:
ref:<SHA> - compile from a vcs (usually git) refprefix:<PREFIX> - use the latest version that matches the prefix. Useful for Go since 1.20
would only match 1.20 exactly but prefix:1.20 will match 1.20.1 and 1.20.2 etc.path:<PATH> - use a custom compiled version at the given path. One use-case is to re-use
Homebrew tools (e.g.: path:/opt/homebrew/opt/node@20).sub-<PARTIAL_VERSION>:<ORIG_VERSION> - subtracts PARTIAL_VERSION from ORIG_VERSION. This can
be used to express something like "2 versions behind lts" such as sub-2:lts. Or 1 minor
version behind the latest version: sub-0.1:latest.mise supports "idiomatic version files" just like asdf. They're language-specific files
like .node-version
and .python-version. These are ideal for setting the runtime version of a project without forcing
other developers to use a specific tool like mise or asdf.
They support aliases, which means you can have an .nvmrc file with lts/hydrogen and it will work
in mise and nvm. Here are some of the supported idiomatic version files:
| Plugin | Idiomatic Files |
|---|---|
| atmos | .atmos-version |
| bun | .bun-version, package.json |
| crystal | .crystal-version |
| deno | .deno-version, package.json |
| dotnet | global.json |
| elixir | .exenv-version |
| go | .go-version |
| java | .java-version, .sdkmanrc |
| node | .nvmrc, .node-version, package.json |
| npm | package.json |
| opentofu | .opentofu-version |
| packer | .packer-version |
| perl | .perl-version |
| pnpm | package.json |
| python | .python-version, .python-versions |
| ruby | .ruby-version, Gemfile |
| rust | rust-toolchain.toml |
| terraform | .terraform-version, main.tf |
| terragrunt | .terragrunt-version |
| terramate | .terramate-version |
| yarn | .yvmrc, package.json |
In mise, these are disabled by default, see https://github.com/jdx/mise/discussions/4345 for rationale.
mise settings add idiomatic_version_file_enable_tools python for a specific tool such as Python (docs)There is a performance cost to having these when they're parsed as it's performed by the plugin in
bin/parse-version-file. However, these are cached so it's not a huge deal.
You may not even notice.
::: info
asdf called these "legacy version files". I think this was a bad name since it implies
that they shouldn't be used—which is definitely not the case IMO. I prefer the term "idiomatic"
version files since they are version files not specific to asdf/mise and can be used by other tools.
(.nvmrc being a notable exception, which is tied to a specific tool.)
:::
See Settings for the full list of settings.
See Tasks for the full list of configuration options.
::: tip Normally environment variables in mise are used to set settings so most environment variables are in that doc. The following are environment variables that are not settings.
A setting in mise is generally something that can be configured either as an environment variable or set in a config file. :::
mise can also be configured via environment variables. The following options are available:
MISE_DATA_DIRDefault (Linux): ~/.local/share/mise or $XDG_DATA_HOME/mise
Default (macOS): ~/.local/share/mise or $XDG_DATA_HOME/mise
Default (Windows): %LOCALAPPDATA%\mise or $XDG_DATA_HOME/mise
This is the directory where mise stores plugins and tool installs. These are not supposed to be shared across machines.
MISE_CACHE_DIRDefault (Linux): ~/.cache/mise or $XDG_CACHE_HOME/mise
Default (macOS): ~/Library/Caches/mise or $XDG_CACHE_HOME/mise
Default (Windows): %TEMP%\mise or $XDG_CACHE_HOME/mise
This is the directory where mise stores internal cache. This is not supposed to be shared across machines. It may be deleted at any time mise is not running.
MISE_TMP_DIRDefault: std::env::temp_dir() implementation
in rust
This is used for temporary storage such as when installing tools.
MISE_SYSTEM_CONFIG_DIRDefault: /etc/mise
This is the directory where mise stores system-wide configuration.
MISE_SYSTEM_DIR is also supported as a legacy alias.
MISE_GLOBAL_CONFIG_FILEDefault: $MISE_CONFIG_DIR/config.toml (Usually ~/.config/mise/config.toml)
This is the path to the config file.
MISE_GLOBAL_CONFIG_ROOTDefault: $HOME
::: v-pre
This is the path which is used as {{config_root}} for the global config file.
:::
MISE_ENV_FILESet to a filename to read from env from a dotenv file. e.g.: MISE_ENV_FILE=.env.
Uses dotenvy under the hood.
MISE_${PLUGIN}_VERSIONSet the version for a runtime. For example, MISE_NODE_VERSION=20 will use [email protected] regardless
of what is set in mise.toml/.tool-versions.
MISE_TRUSTED_CONFIG_PATHSThis is a list of paths that mise will automatically mark as
trusted. They are separated according to platform conventions for the PATH
environment variable: : on Unix and ; on Windows.
MISE_CEILING_PATHSThis is a list of paths where mise will stop searching for
configuration files and file tasks. This is useful to stop
mise searching for files in slow loading directories. They are separated according to platform conventions for the PATH environment variable. On most Unix platforms, the separator is : and on Windows it is ;.
MISE_LOG_LEVEL=trace|debug|info|warn|errorThese change the verbosity of mise.
You can also use MISE_DEBUG=1, MISE_TRACE=1, and MISE_QUIET=1 as well as
--log-level=trace|debug|info|warn|error.
MISE_LOG_FILE=~/mise.logOutput logs to a file.
MISE_LOG_FILE_LEVEL=trace|debug|info|warn|errorSame as MISE_LOG_LEVEL but for the log file output level. This is useful if you want
to store the logs but not have them litter your display.
MISE_LOG_HTTP=1Display HTTP requests/responses in the logs.
MISE_LOG_VERBOSE_DEPS=1Debug and trace logs from noisy third-party crates (h2, hyper,
reqwest, rustls, etc., which emit a line per HTTP/2 frame or socket
read) are always dropped — they would otherwise overwhelm debug/trace
output. Set this to 1 to let those logs through; it is the only way to
see them, including under --log-level=trace/-vv.
MISE_QUIET=1Equivalent to MISE_LOG_LEVEL=warn.
MISE_HTTP_TIMEOUTSet the timeout for http requests in seconds. The default is 30.
MISE_RAW=1Set to "1" to directly pipe plugin scripts to stdin/stdout/stderr. By default stdin is disabled because when installing a bunch of plugins in parallel you won't see the prompt. Use this if a plugin accepts input or otherwise does not seem to be installing correctly.
Sets MISE_JOBS=1 because only 1 plugin script can be executed at a time.
MISE_FISH_AUTO_ACTIVATE=1Configures the vendor_conf.d script for fish shell to automatically activate. This file is automatically used in homebrew and potentially other installs to automatically activate mise without configuring.
Defaults to enabled, set to "0" to disable.