Files
mise/settings.toml
3f0b767f12 feat(http): add ipv4_only setting for hosts that fail over IPv6 (#15057)
On a dual-stack machine where one host answers wrongly over IPv6, mise
had no way to avoid it. In #15047, `dl.google.com` returns `404 Not
Found` over IPv6 and 200 over IPv4, so `mise install go` fails. The
Sigstore TUF trust root fails to load the same way, so `uv` and
`tree-sitter` fail attestation verification (`timestamp.json not
found`). The reporter's only fix was `precedence ::ffff:0:0/96 100` in
`/etc/gai.conf`.

This adds an `ipv4_only` setting that makes mise connect over IPv4 only:

```toml
[settings]
ipv4_only = true
```

or `MISE_IPV4_ONLY=1`. The default is `false`, so nothing changes unless
it is set.

It covers the connections mise makes with its own HTTP client:
downloads, version lookups, GitHub API calls, attestation verification,
vfox plugins and the GitHub relay. Programs mise runs, such as `git`,
`npm` or a tool's installer, still follow the system resolver, and so
does the package manager embedded in the `npm:` backend (aube builds its
own clients); the setting's docs point to `gai.conf` for those. A host
with no IPv4 address cannot be reached while it is on.

Implementation: every client is built through `mise_tls::build_client`,
which now binds the unspecified IPv4 address when the flag is set, and
`load()` in `src/config/settings.rs` pushes the setting into it. The
sigstore library builds its own HTTP client for the default TUF fetch,
so `select_tuf_config` and `github_tuf_trusted_root` now hand it mise's
client when `ipv4_only` is on. Clients built before settings load or
reload keep their address family.

Testing: a `mise-tls` unit test checks that an IPv4-only client cannot
reach a listener on `[::1]` while a default client can. An e2e test
serves a version list over `[::1]` only and over `127.0.0.1`, and checks
that `MISE_IPV4_ONLY=1` makes the IPv6 host fail and the IPv4 host
succeed, while the IPv6 host works without it. Clippy is clean and the
`mise-sigstore` trust tests pass. I did not reproduce the
Google/Sigstore IPv6 failures themselves; they depend on the reporter's
network.

Fixes #15047

*AI-assisted — Tool: Claude Code; model: anthropic/claude-sonnet-5-5;
version: 2.1.308.*

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Alby02 <57523408+Alby02@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 10:29:45 -05:00

4895 lines
190 KiB
TOML

# This file generates code and documentation for settings in mise
# When this file is updated, run `mise run render` to update generated files
[activate_aggressive]
description = "Keep mise's tool directories ahead of `PATH` entries added after `mise activate`."
docs = """
By default, a directory added to `PATH` after `mise activate` takes precedence
over mise's tools. With this in `~/.zshrc`:
```sh
eval "$(mise activate zsh)"
PATH="/some/other/python:$PATH"
```
`python` runs `/some/other/python`, not the version from `mise.toml`. Move
`mise activate` to the end of your shell startup file, or set
`activate_aggressive = true` to keep mise's tools first.
"""
env = "MISE_ACTIVATE_AGGRESSIVE"
type = "Bool"
[activate_shims]
default = true
description = "Let `mise activate` add the shims directories to `PATH` for auto-install and lazy tools."
docs = """
Set to `false` to keep the user and system shims directories out of `PATH`
during `mise activate` and later prompts. Restart your shell after changing it.
Shims provide missing-version auto-installation and first-use installation of
lazy tools, so without them those commands may not be found; run `mise install`
or `mise exec` instead. Installed tools still get their own `bin` directories
on `PATH`.
Command wrappers, such as `cargo` through
[mr-boxington](https://github.com/jdx/mr-boxington), use a separate
`command-wrappers/bin` directory and stay active. `mise activate --shims` adds
shims whatever this is set to. See [Shims](/dev-tools/shims.html#activate-shims).
"""
env = "MISE_ACTIVATE_SHIMS"
type = "Bool"
[age.identity_files]
description = "Age identity files to try when decrypting."
docs = """
Used for age-encrypted `[env]` values and encrypted dotfiles. See
[Decryption identities](/environments/secrets/age.html#decryption-identities)
for the order mise tries identities in.
"""
env = "MISE_AGE_IDENTITY_FILES"
optional = true
parse_env = "list_by_os_path_separator"
rust_type = "Vec<PathBuf>"
type = "ListPath"
[age.key_file]
default_docs = "~/.config/mise/age.txt"
description = "Age private key file used to decrypt and as the default recipient when encrypting."
docs = """
Used for age-encrypted `[env]` values and encrypted dotfiles. See
[Decryption identities](/environments/secrets/age.html#decryption-identities).
"""
env = "MISE_AGE_KEY_FILE"
optional = true
type = "Path"
[age.ssh_identity_files]
description = "SSH private keys to try when decrypting age values."
docs = """
Used for age-encrypted `[env]` values and encrypted dotfiles. See
[Decryption identities](/environments/secrets/age.html#decryption-identities)
for the order mise tries identities in.
"""
env = "MISE_AGE_SSH_IDENTITY_FILES"
optional = true
parse_env = "list_by_os_path_separator"
rust_type = "Vec<PathBuf>"
type = "ListPath"
[age.strict]
default = true
description = "Fail when an `[env]` age value cannot be decrypted, instead of skipping it."
docs = """
Decryption fails when no identity is found, none can decrypt the value, or the
payload is invalid. Set to `false` to skip those variables and resolve the rest
of the environment.
"""
env = "MISE_AGE_STRICT"
type = "Bool"
[all_compile]
default_docs = "`true` on Alpine and NixOS, `false` elsewhere"
description = "Compile Node.js, Python, Ruby and Erlang from source instead of using precompiled builds."
docs = """
Sets the default for [`node.compile`](#node.compile),
[`python.compile`](#python.compile), [`ruby.compile`](#ruby.compile) and
[`erlang.compile`](#erlang.compile); a tool's own setting takes precedence.
Other tools are not affected.
The automatic `true` on Alpine and NixOS is deprecated. Installs that rely on
it have warned since mise 2026.8.0, and from mise 2027.8.0 the default is
`false` everywhere. Set `all_compile = true` to keep building from source.
"""
env = "MISE_ALL_COMPILE"
optional = true
type = "Bool"
[always_keep_download]
deprecated = "Finished downloads are kept in the download cache instead; see download_cache."
deprecated_remove_at = "2027.11.0"
deprecated_warn_at = "2026.11.0"
description = "[deprecated] Keep downloaded archives and sources after installing, for debugging."
docs = """
mise keeps the files under `~/.local/share/mise/downloads` so you can inspect
them while debugging a backend or plugin. Downloads that go through mise's HTTP
client are kept in [`download_cache`](#download_cache) instead, under their own
names, so this is only needed for files an asdf plugin script downloads itself.
"""
env = "MISE_ALWAYS_KEEP_DOWNLOAD"
type = "Bool"
[always_keep_install]
description = "Keep a failed installation's partial install directory and downloads, for debugging."
env = "MISE_ALWAYS_KEEP_INSTALL"
type = "Bool"
[aqua.baked_registry]
default = true
description = "Use the aqua registry built into mise."
docs = """
Set to `false` to resolve aqua packages only from
[`aqua.registries`](#aqua.registries), or, when none are configured, from the
official registry downloaded from GitHub.
"""
env = "MISE_AQUA_BAKED_REGISTRY"
type = "Bool"
[aqua.cosign]
default = true
description = "Verify Cosign signatures for aqua packages that declare them."
docs = "mise verifies the signatures itself; no `cosign` binary is needed."
env = "MISE_AQUA_COSIGN"
type = "Bool"
[aqua.github_attestations]
default = true
description = "Verify GitHub artifact attestations for aqua packages that declare them."
docs = """
Has no effect when the global
[`github_attestations`](/configuration/settings.html#github_attestations)
setting is `false`.
"""
env = "MISE_AQUA_GITHUB_ATTESTATIONS"
type = "Bool"
[aqua.minisign]
default = true
description = "Verify Minisign signatures for aqua packages that declare them."
docs = "mise verifies the signatures itself; no `minisign` binary is needed."
env = "MISE_AQUA_MINISIGN"
type = "Bool"
[aqua.registries]
description = "Aqua registries to search, in order, before the baked-in registry."
docs = """
Each entry is a repository URL, a URL to a `registry.yaml` file, an absolute
`file://` URL, or a path relative to the config file that sets it. For a
repository or directory, mise reads `registry.yaml` at its root, or
`registry.yml` when that is missing.
```toml
[settings]
aqua.registries = ["https://github.com/my-org/aqua-registry", "registry.yaml"]
```
Relative paths resolve only from config files, so a path in
`MISE_AQUA_REGISTRIES` must be an absolute `file://` URL. `mise settings`
writes the value into a config file, so a relative path set that way resolves
against that file's config root (`$HOME` for the global config).
While [`aqua.baked_registry`](#aqua.baked_registry) is on, the baked-in registry
is the fallback for packages these registries do not define. With
[`registry_floating`](/configuration/settings.html#registry_floating), mise
also downloads the official aqua registry and checks it after the configured
registries and before the baked-in one, falling back to the baked-in registry
if the download fails. Downloaded registries are cached for
[`aqua.registry_cache_ttl`](#aqua.registry_cache_ttl); `file://` registries are
read directly. See [Custom registry](/dev-tools/backends/aqua.html#custom-registry).
"""
env = "MISE_AQUA_REGISTRIES"
optional = true
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[aqua.registry_cache_ttl]
default_docs = "1w"
description = "How long a downloaded aqua registry stays fresh before mise downloads it again."
docs = """
Set to `0s` to download remote registries every time mise loads them. Local
`file://` registries are always read directly.
"""
env = "MISE_AQUA_REGISTRY_CACHE_TTL"
optional = true
type = "Duration"
[aqua.registry_url]
deprecated = "Use aqua.registries instead."
deprecated_remove_at = "2027.12.0"
deprecated_warn_at = "2026.12.0"
description = "[deprecated] URL of one aqua registry repository to search before the baked-in registry."
docs = "When both are set, [`aqua.registries`](#aqua.registries) takes precedence."
env = "MISE_AQUA_REGISTRY_URL"
optional = true
type = "String"
[aqua.slsa]
default = true
description = "Verify SLSA provenance for aqua packages that declare it."
docs = """
Has no effect when the global [`slsa`](/configuration/settings.html#slsa)
setting is `false`.
"""
env = "MISE_AQUA_SLSA"
type = "Bool"
[arch]
default_docs = "host architecture"
description = "Architecture of the precompiled binaries mise downloads."
docs = """
`x86_64` and `amd64` mean `x64`, and `aarch64` means `arm64`; other values, such
as `arm`, `loongarch64` or `riscv64`, are used as written. Set it to install
binaries for another architecture, for example on a machine that runs x64
binaries under emulation.
"""
env = "MISE_ARCH"
optional = true
type = "String"
[asdf_compat]
deprecated = "no longer supported"
description = "Write `.tool-versions` files that asdf can read, with exact versions."
docs = """
When `true`, `mise use` pins exact versions, new config files are
`.tool-versions` instead of `mise.toml`, and the global config file is
`~/.tool-versions`.
"""
env = "MISE_ASDF_COMPAT"
hide = true
type = "Bool"
[auto_env]
default_docs = "`false` (`true` from mise 2027.6.0)"
description = "Automatically enable platform config environments (unix, {os}, {os}-{arch})."
docs = """
When enabled, mise treats these as active config environments, in addition to
any explicit `MISE_ENV`: `unix` on Unix-family platforms, the OS name (`linux`,
`macos` or `windows`), and `{os}-{arch}`, such as `macos-arm64` or
`windows-x64`. Architecture names follow mise's spelling: `x86_64` becomes `x64`
and `aarch64` becomes `arm64`.
Config files such as `mise.windows.toml`, `mise/config.macos-arm64.toml` or
`mise.unix.toml` then load automatically, and matching `mise.<env>.lock`
lockfiles are selected. Platform environments rank below explicit `MISE_ENV`
entries: `unix` < `{os}` < `{os}-{arch}` < explicit `MISE_ENV` entries. They do
not change the `{{ mise_env }}` template variable or the `MISE_ENV` variable
passed to subprocesses.
Set it to `false` to keep today's behavior after the default changes. See
[Platform environments](/configuration/environments.html#platform-environments).
"""
env = "MISE_AUTO_ENV"
optional = true
rc = true
type = "Bool"
[auto_install]
default = true
description = "Install missing tools automatically when a command needs them."
docs = """
When `false`, mise never installs automatically: this also turns off
[`exec_auto_install`](#exec_auto_install),
[`not_found_auto_install`](#not_found_auto_install) and
[`task.run_auto_install`](#task.run_auto_install). To skip only some tools, use
[`auto_install_disable_tools`](#auto_install_disable_tools). See
[Auto-install mechanisms](/dev-tools/#auto-install-mechanisms).
"""
env = "MISE_AUTO_INSTALL"
type = "Bool"
[auto_install_disable_tools]
description = "Tools that automatic installs skip, such as `node`."
docs = """
Applies to every automatic install, such as from `mise exec`, `mise run` or the
command-not-found handler. Install these tools yourself with `mise install`.
"""
env = "MISE_AUTO_INSTALL_DISABLE_TOOLS"
optional = true
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[auto_update]
default_docs = "false"
deprecated = "Use self_update.auto instead."
deprecated_remove_at = "2028.4.0"
deprecated_warn_at = "2027.4.0"
description = "[deprecated] Old name for `self_update.auto`."
docs = """
mise still reads this setting and `MISE_AUTO_UPDATE` when
[`self_update.auto`](#self_update.auto) is not set.
"""
env = "MISE_AUTO_UPDATE"
global_only = true
optional = true
type = "Bool"
[auto_update_check_duration]
default_docs = "7d"
deprecated = "Use self_update.check_duration instead."
deprecated_remove_at = "2028.4.0"
deprecated_warn_at = "2027.4.0"
description = "[deprecated] Old name for `self_update.check_duration`."
docs = """
mise still reads this setting and `MISE_AUTO_UPDATE_CHECK_DURATION` when
[`self_update.check_duration`](#self_update.check_duration) is not set.
"""
env = "MISE_AUTO_UPDATE_CHECK_DURATION"
global_only = true
optional = true
type = "Duration"
[cache_prune_age]
default = "30d"
description = "Delete cache files that have not been accessed for this long."
docs = """
mise deletes such files from time to time on its own, and
[`mise cache prune`](/cli/cache/prune.html) uses the same age. Set to `0s` to
keep cache files indefinitely; both the automatic sweep and `mise cache prune`
then skip pruning.
This covers the cache directories only. Cached environments expire by
[`env_cache_ttl`](#env_cache_ttl) instead. See
[Cache auto-pruning](/cache-behavior.html#cache-auto-pruning).
"""
env = "MISE_CACHE_PRUNE_AGE"
type = "Duration"
[cargo.binstall]
default = true
description = "Install Cargo tools from cargo-binstall's prebuilt binaries when cargo-binstall is installed."
docs = """
mise uses a `cargo-binstall` installed through mise or found on `PATH`, and runs
`cargo install` when it has no prebuilt binary. A prebuilt binary ignores your
Cargo build configuration, so set this to `false` when that configuration must
apply. Install cargo-binstall with `mise use -g cargo-binstall`. See
[How mise installs a crate](/dev-tools/backends/cargo.html#how-mise-installs-a-crate).
"""
env = "MISE_CARGO_BINSTALL"
type = "Bool"
[cargo.binstall_native]
description = "Use mise's own prebuilt-binary installer for Cargo tools when cargo-binstall is not installed."
docs = """
The installer downloads binaries described by `package.metadata.binstall` in the
crate's `Cargo.toml`, or named the usual way in the GitHub releases of the
crate's repository. It runs `cargo install` instead when it finds no binary or
the install uses Cargo build options that would change the result.
- `true`: try this installer before `cargo install`.
- `false`: never use it.
- unset: do not use it. From mise 2027.1.0, mise warns when a crate could have
been installed this way, and from mise 2027.7.0 unset means `true`.
Setting [`cargo.binstall`](#cargo.binstall) to `false` turns this installer off
too.
"""
env = "MISE_CARGO_BINSTALL_NATIVE"
optional = true
type = "Bool"
[cargo.binstall_only]
default = false
description = "Require prebuilt binaries from cargo-binstall instead of falling back to `cargo install`."
docs = """
Installs fail when cargo-binstall is missing or turned off, has no prebuilt
binary, or a tool option such as `features` needs `cargo install`. Tools from a
Git source are unaffected; they always build with `cargo install --git`.
"""
env = "MISE_CARGO_BINSTALL_ONLY"
type = "Bool"
[cargo.binstall_quickinstall]
default = false
description = "Let cargo-binstall download third-party artifacts from cargo-quickinstall."
docs = """
By default, mise passes `--disable-strategies compile,quick-install` to
cargo-binstall, so it uses only artifacts that the crate's authors publish,
never [cargo-quickinstall](https://github.com/cargo-bins/cargo-quickinstall)
builds. With `true`, mise passes `--disable-strategies compile` instead. mise's
own installer ([`cargo.binstall_native`](#cargo.binstall_native)) never uses
quickinstall.
"""
env = "MISE_CARGO_BINSTALL_QUICKINSTALL"
type = "Bool"
[cargo.registry_name]
description = "Cargo registry to install crates from instead of crates.io."
docs = """
The name of an
[alternate registry](https://doc.rust-lang.org/cargo/reference/registries.html#using-an-alternate-registry)
defined in your Cargo configuration (`[registries.<name>]`), such as a private
mirror. mise passes it to `cargo install` as `--registry`, and does not use its
own prebuilt-binary installer while it is set.
"""
env = "MISE_CARGO_REGISTRY_NAME"
optional = true
type = "String"
[cd]
description = "Directory to change to after mise starts."
env = "MISE_CD"
hide = true
optional = true
type = "Path"
[ceiling_paths]
default = []
description = "Directories where mise stops searching parent directories for config files."
docs = """
By default, mise looks for config files in the current directory and every
parent up to the filesystem root. The search stops at a ceiling directory, which
is not searched itself: with `MISE_CEILING_PATHS=/home/user`,
`/home/user/projects/app/mise.toml` loads but `/home/user/mise.toml` does not.
This matches Git's `GIT_CEILING_DIRECTORIES`.
`mise settings` and `mise settings add` refuse this setting, because mise
reads it before config files load; put it in a `.miserc.toml` file or the
environment variable instead.
"""
env = "MISE_CEILING_PATHS"
parse_env = "list_by_os_path_separator"
rc = true
rust_type = "BTreeSet<PathBuf>"
type = "ListPath"
[ci]
default = "false"
description = "Behave as in CI, which answers yes to confirmation prompts; read from the `CI` variable."
deserialize_with = "bool_string"
env = "CI"
global_only = true
hide = true
type = "Bool"
[color]
default = true
description = "Use color in mise's terminal output."
env = "MISE_COLOR"
type = "Bool"
[color_theme]
default = "default"
description = "Color theme for interactive prompts, such as the task picker in `mise run`."
docs = """
With colors off (`color = false`, `NO_COLOR` or `CLICOLOR=0`), prompts are
unstyled whatever this is set to.
"""
enum = [
{ value = "auto", description = "`base16` on light terminals (detected from `COLORFGBG`), `charm` otherwise" },
{ value = "default", description = "same as `auto`" },
{ value = "charm", description = "suits dark terminals" },
{ value = "base16", description = "suits light terminals" },
{ value = "catppuccin" },
{ value = "dracula" },
]
env = "MISE_COLOR_THEME"
type = "String"
[conda.channel]
default = "conda-forge"
description = "Channel for `conda:` tools that do not set their own."
docs = """
The package and all of its dependencies must come from this one channel.
Override it for one tool with the
[`channel`](/dev-tools/backends/conda.html#channel) tool option.
"""
env = "MISE_CONDA_CHANNEL"
type = "String"
[debug]
description = "Set the log level to debug."
env = "MISE_DEBUG"
hide = true
type = "Bool"
[default_config_filename]
default = "mise.toml"
description = "Extra project config filename mise reads, and the name it gives new config files."
docs = """
mise still reads `mise.toml` and the other standard names. To move the global
config, use [`global_config_file`](#global_config_file); to replace the list of
names mise reads, use [`override_config_filenames`](#override_config_filenames).
"""
env = "MISE_DEFAULT_CONFIG_FILENAME"
env_only = true
type = "String"
[default_tool_versions_filename]
default = ".tool-versions"
description = "Extra filename mise reads as a `.tool-versions` file."
docs = """
`.tool-versions` files are still read; to stop reading them, use
[`override_tool_versions_filenames`](#override_tool_versions_filenames).
"""
env = "MISE_DEFAULT_TOOL_VERSIONS_FILENAME"
env_only = true
type = "String"
[disable_backends]
default = []
description = "Backends mise ignores when resolving and installing tools, such as `asdf` or `pypi`."
docs = """
Tools already installed with a disabled backend stay on disk and work again once
you re-enable it. A vfox backend plugin can be disabled by its plugin name.
"""
env = "MISE_DISABLE_BACKENDS"
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[disable_default_registry]
description = "Stop mapping short names such as `php` to the asdf and vfox plugins listed in the registry."
env = "MISE_DISABLE_DEFAULT_REGISTRY"
type = "Bool"
[disable_hints]
default = []
description = "Hints to stop showing, by ID; `*` turns off every hint."
docs = """
mise shows each hint once and records it in `$MISE_STATE_DIR/hints`. To turn
one off before it appears, or all of them:
```sh
mise settings add disable_hints python_multi
mise settings add disable_hints '*'
```
Hint IDs include `tools_missing`, `python_multi`, `python_precompiled`,
`ruby_precompiled`, `upgrade_auto_prune` and `skills`.
"""
env = "MISE_DISABLE_HINTS"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[disable_tools]
default = []
description = "Tools mise ignores even when a config file lists them."
docs = "Ignored when [`enable_tools`](#enable_tools) is set."
env = "MISE_DISABLE_TOOLS"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[disable_update_warning]
default = false
description = "Suppress warnings when a newer mise version is available."
docs = """
Hides the update notice in `mise version`, `mise --version` and `mise doctor`.
Other warnings are unaffected. It does not turn off `mise self-update` or
automatic updates with [`self_update.auto`](#self_update.auto).
"""
env = "MISE_DISABLE_UPDATE_WARNING"
type = "Bool"
[dotfiles.default_mode]
default = "symlink"
description = "Mode for `[dotfiles]` entries that do not set `mode`."
docs = """
Applies to entries without `mode`, including string entries such as
`"~/.vimrc" = "vimrc"`, and to `mise dot add` without `--mode`. `track` and
`absent` cannot be the default; set them on each entry. An unsupported value
falls back to `symlink` with a warning. See [Modes](/dotfiles/managed.html#modes).
"""
enum = [
{ value = "symlink", description = "link the target to its source" },
{ value = "symlink-each", description = "create directories and link each file in them" },
{ value = "copy", description = "copy the source to the target" },
{ value = "template", description = "render the source as a template" },
]
env = "MISE_DOTFILES_DEFAULT_MODE"
type = "String"
[dotfiles.relative_symlinks]
default = false
description = "Create dotfile symlinks with relative targets instead of absolute ones."
docs = """
Applies to `symlink` and `symlink-each` entries; an entry's `relative` key
overrides it. Relative links keep working when the home directory is mounted at
a different path on another machine or the tree is moved, as long as the target
and source keep their positions relative to each other. Ignored on Windows,
where directory links are junctions, which cannot be relative. See
[relative](/dotfiles/managed.html#relative).
"""
env = "MISE_DOTFILES_RELATIVE_SYMLINKS"
type = "Bool"
[dotfiles.root]
default = "~/.dotfiles"
description = "Directory that holds dotfile sources for entries without a `source`."
docs = """
`~/.zshrc` reads its source from `<root>/.zshrc`, and `mise dot add` saves new
sources here. Relative `[dotfile_groups]` roots and the relative keys of
destination-variant entries also resolve against it. See
[Whole-file entries](/dotfiles/managed.html#whole-file-entries).
In a config file, the value may be a template such as
`{{ mise_config_dir }}/home`, which keeps the sources beside a dotfiles
repository adopted as the global config. A relative result resolves against
the config root.
"""
env = "MISE_DOTFILES_ROOT"
type = "Path"
[dotfiles.windows_symlinks]
default = false
description = "On Windows, deploy dotfile files as symbolic links instead of copies."
docs = """
By default `symlink-each` copies each file on Windows, and `symlink` links a
file only when Windows allows it and otherwise copies it. With this on, both
create real file symbolic links and fail when Windows refuses, rather than
leaving a copy that no longer follows its source. Creating them needs
Developer Mode or an elevated shell. Directory links are always junctions.
Ignored on other platforms. See [Windows](/dotfiles/managed.html#windows).
"""
env = "MISE_DOTFILES_WINDOWS_SYMLINKS"
type = "Bool"
[dotnet.cli_telemetry_optout]
description = "Set `DOTNET_CLI_TELEMETRY_OPTOUT` to opt out of .NET CLI telemetry."
docs = """
`true` sets `DOTNET_CLI_TELEMETRY_OPTOUT=1` and `false` sets it to `0`. When
unset, mise leaves the variable alone and .NET uses its own default.
"""
env = "MISE_DOTNET_CLI_TELEMETRY_OPTOUT"
optional = true
type = "Bool"
[dotnet.dotnet_root]
default_docs = "`$DOTNET_ROOT` when set, otherwise `~/.local/share/mise/dotnet-root`"
description = "Shared directory that every .NET SDK version installs into."
docs = """
SDK versions install side by side here, matching .NET's own multi-version
layout. Ignored when [`dotnet.isolated`](#dotnet.isolated) is `true`.
"""
env = "MISE_DOTNET_ROOT"
optional = true
type = "Path"
[dotnet.isolated]
default = false
description = "Install each .NET SDK version in its own isolated directory."
docs = """
With `true`, each SDK version installs under mise's installs directory like
other tools, and `dotnet --list-sdks` shows only the active one. With `false`,
every version shares [`dotnet.dotnet_root`](#dotnet.dotnet_root) and
`dotnet --list-sdks` lists all of them.
"""
env = "MISE_DOTNET_ISOLATED"
type = "Bool"
[dotnet.package_flags]
default = []
deprecated = "Use the `prerelease = true` tool option or the global `prereleases` setting instead."
deprecated_remove_at = "2027.11.0"
deprecated_warn_at = "2026.11.0"
description = "[deprecated] Flags for every `dotnet:` tool; the only flag, `prerelease`, includes prereleases."
docs = """
Because it applies to every tool, `prerelease` here also overrides a tool's own
`prerelease = false`.
"""
env = "MISE_DOTNET_PACKAGE_FLAGS"
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[dotnet.registry_url]
default = "https://api.nuget.org/v3/index.json"
description = "NuGet service index used to discover dotnet tool versions."
docs = """
Installation runs `dotnet tool install`, which reads its own `NuGet.Config` and
credentials. Configure a private feed there as well; this setting does not add
an installation source to the dotnet CLI.
"""
env = "MISE_DOTNET_REGISTRY_URL"
type = "Url"
[download_cache]
default = true
description = "Reuse finished downloads instead of fetching them again."
docs = """
mise keeps finished downloads in `$MISE_CACHE_DIR/downloads-cas`, named by their
hash, and uses one again in two cases:
- **The server confirms it is unchanged.** The next request for the same URL
carries the `ETag` or `Last-Modified` value the server sent, and a
`304 Not Modified` answer means the kept file is used instead of a new
download. Servers that send no validator are not cached.
- **A tool pinned its checksum**, in its options or in `mise.lock`, and the kept
file was downloaded from the same URL. It is used with no request at all. A
file another URL served is not, even when it has that checksum, and neither
is anything for a checksum `mise lock` took from mise-versions without
downloading (see [`mise.lock`](/dev-tools/mise-lock.html#checksums)).
The `http`, `github`, `aqua` and `packslip` backends and the core tools'
precompiled archives pin and install from the stored file, linked into place
where the filesystem allows, so the archive takes no extra space and is not
copied; across devices it is copied. The core tools pin with the checksum in
`mise.lock`. Node's source tarball is kept the same way and compiled each time.
Other source builds, such as Ruby and Python through `ruby-build` and
`python-build`, download their own sources, which are not kept. Every other
download that goes through mise's HTTP client uses the first case and is copied
into place.
With [`locked`](#locked) or [`paranoid`](#paranoid), only downloads with a
pinned checksum are reused or kept, since only those are checked afterwards.
Restoring `downloads-cas` in CI then gives a cache you can trust, which a
restored install directory is not.
A kept file is hashed again before it is used, and one that no longer matches is
dropped and downloaded again. The recorded hash lives beside the file, so this
catches damage but does not stop someone who can write the cache from replacing
both. A pinned checksum is always checked after the download, so pin one if the
cache is shared. The cache holds up to
[`download_cache_max_size`](#download_cache_max_size); the least recently used
entries go first. Extracted files are not covered; see
[Restored caches and installed tools](/dev-tools/mise-lock.html#restored-caches).
"""
env = "MISE_DOWNLOAD_CACHE"
type = "Bool"
[download_cache_max_size]
default = "2GiB"
description = "Maximum total size of the download cache, such as `500MB` or `10GiB`."
docs = """
After storing a download, mise removes the least recently used ones until the
cache in `$MISE_CACHE_DIR/downloads-cas` fits. A download used in the last ten
minutes is kept, since another install may be placing it. `0` means no limit.
See [`download_cache`](#download_cache).
"""
env = "MISE_DOWNLOAD_CACHE_MAX_SIZE"
type = "String"
[enable_tools]
description = "Allowlist of configured tools mise uses; other tools are ignored."
docs = """
When unset, mise uses every configured tool except those in
[`disable_tools`](#disable_tools). Once set, this list is the complete
allowlist and `disable_tools` is ignored. An empty list (`[]`, or
`MISE_ENABLE_TOOLS=` with nothing after it) disables every tool.
"""
env = "MISE_ENABLE_TOOLS"
optional = true
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[env]
default = []
description = "Config environments to load, such as `development` for `mise.development.toml`."
docs = """
Selects which [config environments](/configuration/environments.html) load, so
`mise.development.toml` applies only when `development` is set. Separate several
with commas, such as `MISE_ENV=ci,test`; later ones take precedence. The
`-E`/`--env` flag sets it for one command.
"""
env = "MISE_ENV"
parse_env = "list_by_comma"
rc = true
type = "ListString"
[env_cache]
default = false
description = "[experimental] Cache computed environments on disk for nested mise commands."
docs = """
Caches environment variables and `PATH` so nested commands such as
`mise exec -- mise env` skip recomputing them. Entries expire after
[`env_cache_ttl`](#env_cache_ttl) or when config files, tool versions, settings,
or files that env plugins watch change. Edits to dotenv files or `_.source`
scripts may not invalidate an entry; set `MISE_ENV_CACHE=0` for a command that
must recompute. Configurations with secrets (an `age` value, a sops-encrypted
file or `redact = true`) are never cached. See
[Environment cache](/cache-behavior.html#environment-caching).
"""
env = "MISE_ENV_CACHE"
type = "Bool"
[env_cache_ttl]
default = "1h"
description = "How long a cached environment stays valid."
docs = """
Entries are also invalidated when config files, tool versions, settings or
watched files change.
"""
env = "MISE_ENV_CACHE_TTL"
type = "Duration"
[env_conf_d]
default_docs = "`false` (`true` from mise 2027.8.10)"
description = "Enable environment-specific filenames in conf.d directories."
docs = """
With this on, a `conf.d` fragment with an environment in its name loads only
when that environment is active: `tools.development.toml` loads only with
`development`, and `tools.development.local.toml` is its local variant. It
applies to every `conf.d` directory: `mise/conf.d`, `.mise/conf.d`,
`.config/mise/conf.d`, `~/.config/mise/conf.d` and `/etc/mise/conf.d`. With it
off, every non-hidden TOML file in `conf.d` loads.
Dots in the names of unconditional fragments are deprecated; rename
`node.tools.toml` to `node-tools.toml` before the default changes. See
[conf.d environments](/configuration/environments.html#conf-d-environments).
"""
env = "MISE_ENV_CONF_D"
optional = true
rc = true
type = "Bool"
[env_file]
description = "Dotenv file names to load from the current directory and each parent directory."
deserialize_with = "path_or_paths"
docs = """
mise loads every file with one of these names, such as `.env` and `.env.local`,
between the filesystem root and the current directory. When a variable appears
in more than one file, the file nearest the current directory wins, and within
one directory a name later in the list wins. An absolute path loads that one
file. For a dotenv file that belongs to one project, use
[`_.file`](/environments/#env-file) in `mise.toml` instead.
```toml [~/.config/mise/config.toml]
[settings]
env_file = [".env", ".env.local"]
```
`MISE_ENV_FILE` takes the names separated by `:` (`;` on Windows).
These values are applied after every config file's `[env]`, so they override
it, except for a file that an `_.file` entry has already loaded, which this
setting skips. An [`_.file`](/environments/#env-file) entry, including one with
`find_up = true` in a global config, is an ordinary `[env]` entry that a
project's own `[env]` values can override.
"""
env = "MISE_ENV_FILE"
optional = true
parse_env = "list_by_os_path_separator"
rust_type = "Vec<PathBuf>"
type = "ListPath"
[env_shell_expand]
default = true
description = "Expand shell-style variables such as `$FOO` and `${BAR:-default}` in `[env]` values."
docs = """
```toml
[env]
FOO = "hello"
BAR = "$FOO-world" # "hello-world"
BAZ = "${FOO}_suffix" # "hello_suffix"
QUX = "${UNDEF:-fallback}" # "fallback"
```
Expansion runs after Tera templates render, so both syntaxes can be mixed. An
undefined variable stays as written and logs a warning; write `${MISSING:-}` to
expand it to an empty string without one. Set to `false` to leave `$`
sequences untouched. See
[Shell-style variable expansion](/environments/#shell-style-variable-expansion).
"""
env = "MISE_ENV_SHELL_EXPAND"
type = "Bool"
[erlang.compile]
description = "Compile Erlang from source instead of using a precompiled build."
docs = """
`true` always builds from source with kerl. `false` uses only precompiled builds
and fails when none exists for the platform. When unset,
[`all_compile`](/configuration/settings.html#all_compile) decides; if that is
unset too, mise uses a precompiled build when one is available and builds from
source otherwise.
"""
env = "MISE_ERLANG_COMPILE"
optional = true
type = "Bool"
[erlang.precompiled_os]
description = "Ubuntu release whose precompiled Erlang build from builds.hex.pm mise installs on Linux."
docs = """
Applies to glibc Linux targets, including `mise lock` for Linux platforms from
another OS, which otherwise assumes `ubuntu-24.04`. When unset on Linux, mise
derives it from `$ImageOS` (GitHub Actions) or `/etc/os-release`, and uses
precompiled builds automatically only for Ubuntu 20.04, 22.04 and 24.04. Set it
to `ubuntu-26.04` on that release, or to one of these Ubuntu releases on another
glibc distribution to use that release's build; other values are rejected.
musl Linux always builds from source.
"""
enum = ["ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04", "ubuntu-26.04"]
env = "MISE_ERLANG_PRECOMPILED_OS"
optional = true
type = "String"
[exec_auto_install]
default = true
description = "Install missing tools automatically when you run `mise exec`."
docs = "Has no effect when [`auto_install`](#auto_install) is `false`."
env = "MISE_EXEC_AUTO_INSTALL"
type = "Bool"
[experimental]
description = "Enable experimental features, which may change or be removed in any release."
docs = """
Turns on features that are still being designed. An experimental feature can
change or disappear in any release; once it leaves experimental, changes follow
the normal deprecation process. A feature's docs say when it needs this
setting.
Some new behavior also ships behind this flag before it becomes the default, so
enabling it helps catch problems early. If something breaks after you enable
it, check whether it still happens with `experimental = false`, then
[open an issue](https://github.com/jdx/mise/issues).
"""
env = "MISE_EXPERIMENTAL"
type = "Bool"
[extract_max_ratio]
default = 100
description = "How many times its own size a downloaded archive or compressed file may unpack to."
docs = """
A small download can be built to unpack to far more data than the disk holds:
1 GiB of zeroes is under 1 KiB of bzip2. When mise unpacks a tool's archive or
compressed file, it stops, and the install fails, once the output is larger
than 256 MiB and more than this many times the size of the download. Tool
archives rarely unpack to more than 10 times their size.
Raise it for a tool that legitimately unpacks to more, such as an archive of
mostly empty disk images. `0` means no limit.
"""
env = "MISE_EXTRACT_MAX_RATIO"
global_only = true
type = "Integer"
[fetch_remote_versions_cache]
default_docs = "1h"
description = "How long a tool's cached list of available versions stays fresh."
docs = """
`mise outdated`, `mise upgrade`, `mise ls-remote`, `mise lock` and `mise latest`
fetch the list again once it is older than this, 1 hour by default.
When this is not set, commands that only need a version matching a request,
such as `mise install`, `mise use` and `mise run`, keep a list for the tool's
[`minimum_release_age`](#minimum_release_age) less an hour, the most a
versions-host snapshot lags: 23 hours by default, 5 hours for a tool with
`minimum_release_age = "6h"`, and never less than 1 hour or more than 24 hours.
A release newer than the list could not be picked before it reached that age
anyway. This applies only to lists that date every
version; others are refetched after 1 hour. Setting this value applies it to
every command.
Commands that prefer offline data, such as shims, `mise activate`, `mise exec`,
`mise env` and `mise ls`, use the cached list whatever its age, as does every
command when [`prefer_offline`](#prefer_offline) is on. The same duration
controls when remote `include` fragments that point at a branch or tag are
refreshed. See
[When mise refreshes version lists](/cache-behavior.html#version-list-refresh).
"""
env = "MISE_FETCH_REMOTE_VERSIONS_CACHE"
optional = true
type = "Duration"
[fetch_remote_versions_timeout]
aliases = ["fetch_remote_version_timeout"]
default = "20s"
description = "Timeout for looking up a tool's available versions."
docs = """
Applies to HTTP requests to version sources and to version-listing commands that
backends run, such as `go list` or an asdf plugin's scripts. A bare number is
seconds.
Commands that prefer offline data, such as shims, shell activation,
`mise exec`, `mise env` and `mise ls`, cap this at 3 seconds and do not retry,
so they do not hang when the network is down. `mise lock`, `mise ls-remote`,
`mise outdated` and `mise upgrade` always use the full timeout.
"""
env = "MISE_FETCH_REMOTE_VERSIONS_TIMEOUT"
type = "Duration"
[forgejo.credential_command]
default = ""
description = "Command that prints a Forgejo token on stdout."
docs = """
mise runs the command with the default inline shell
([`unix_default_inline_shell_args`](/configuration/settings.html#unix_default_inline_shell_args)
or
[`windows_default_inline_shell_args`](/configuration/settings.html#windows_default_inline_shell_args))
and uses its trimmed output as the token. The command receives
`MISE_CREDENTIAL_HOST`, the host that needs a token, so one command can serve
several self-hosted Forgejo servers, and `MISE_CREDENTIAL_PROVIDER=forgejo`.
mise tries it right after the token environment variables; if it fails or
prints nothing, mise moves on to the next source. It does not need
[`forgejo.use_git_credentials`](#forgejo.use_git_credentials).
```toml [~/.config/mise/config.toml]
[settings.forgejo]
credential_command = 'op read "op://Private/Forgejo Token/credential"'
```
See [Credential command](/dev-tools/github-tokens.html#credential-command) and
[Token priority](/dev-tools/github-tokens.html#token-priority).
"""
env = "MISE_FORGEJO_CREDENTIAL_COMMAND"
global_only = true
type = "String"
[forgejo.fj_cli_tokens]
default = true
description = "Read Forgejo tokens that the fj CLI stores in its `keys.json` file."
docs = """
See [CLI logins](/dev-tools/github-tokens.html#cli-logins) for where mise looks
for the file and [Token priority](/dev-tools/github-tokens.html#token-priority)
for when it is used.
"""
env = "MISE_FORGEJO_FJ_CLI_TOKENS"
type = "Bool"
[forgejo.use_git_credentials]
default = false
description = "Get Forgejo tokens from your Git credential helpers with `git credential fill`."
docs = """
This reaches tokens kept by helpers such as the macOS Keychain or Windows
Credential Manager. mise tries it last, after the environment variables,
[`forgejo.credential_command`](#forgejo.credential_command),
`forgejo_tokens.toml` and fj CLI tokens, and caches the result per host while
it runs. See
[Git credential helpers](/dev-tools/github-tokens.html#git-credential-helpers).
"""
env = "MISE_FORGEJO_USE_GIT_CREDENTIALS"
type = "Bool"
[github.credential_command]
default = ""
description = "Command that prints a GitHub token on stdout."
docs = """
mise runs the command with the default inline shell
([`unix_default_inline_shell_args`](/configuration/settings.html#unix_default_inline_shell_args)
or
[`windows_default_inline_shell_args`](/configuration/settings.html#windows_default_inline_shell_args))
and uses its trimmed output as the token. The command receives
`MISE_CREDENTIAL_HOST`, the host that needs a token, so one command can serve
github.com and GitHub Enterprise hosts, and `MISE_CREDENTIAL_PROVIDER=github`.
mise tries it right after the token environment variables and before native
GitHub OAuth; if it fails or prints nothing, mise moves on to the next source.
It does not need [`github.use_git_credentials`](#github.use_git_credentials).
```toml [~/.config/mise/config.toml]
[settings.github]
credential_command = 'op read "op://Private/GitHub Token/credential"'
```
See [Credential command](/dev-tools/github-tokens.html#credential-command) and
[Token priority](/dev-tools/github-tokens.html#token-priority).
"""
env = "MISE_GITHUB_CREDENTIAL_COMMAND"
global_only = true
type = "String"
[github.enterprise_hosts]
default = []
description = "Extra GitHub Enterprise hosts that receive your GitHub token on their `/api/v3` URLs."
docs = """
mise sends the GitHub token to `api.github.com` and `api.*.ghe.com`, and to
an `/api/v3` URL only on the origin of the tool's
[`api_url`](/dev-tools/backends/github.html#api-url). A GitHub Enterprise
Server URL that reaches mise any other way, such as an `http:` tool, an aqua
package or a remote task file under `https://github.mycompany.com/api/v3/`,
gets no token. List the hosts that should get one:
```toml [~/.config/mise/config.toml]
[settings.github]
enterprise_hosts = ["github.mycompany.com"]
```
The token is sent over `https` only, to any port of a listed host, and only on
paths under `/api/v3`. mise ignores this setting in project config, since a
repository could otherwise list a host of its choosing. See
[GitHub Enterprise](/dev-tools/github-tokens.html#github-enterprise).
"""
env = "MISE_GITHUB_ENTERPRISE_HOSTS"
global_only = true
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[github.gh_cli_tokens]
default = true
description = "Read GitHub tokens that the gh CLI stores in its `hosts.yml` file."
docs = """
gh stores a token per host, so this also covers GitHub Enterprise hosts. Tokens
that gh keeps in the system keyring are not in `hosts.yml`; see
[If gh keeps its token in the system keyring](/dev-tools/github-tokens.html#gh-keyring).
See [CLI logins](/dev-tools/github-tokens.html#cli-logins) for where mise looks
for the file and [Token priority](/dev-tools/github-tokens.html#token-priority)
for when it is used.
"""
env = "MISE_GITHUB_GH_CLI_TOKENS"
type = "Bool"
[github.github_attestations]
default = true
description = "Verify GitHub artifact attestations for github backend tools."
docs = """
Attestations are checked only when this setting, the global
[`github_attestations`](/configuration/settings.html#github_attestations)
setting and the tool's own `github_attestations` option are all `true`; set the
option to `false` to skip one tool. Tools with a custom `api_url`, such as those
on GitHub Enterprise Server, are not checked, because that API has no
attestations endpoint.
"""
env = "MISE_GITHUB_GITHUB_ATTESTATIONS"
type = "Bool"
[github.oauth_api_url]
default = "https://api.github.com"
description = "GitHub API base URL mise uses to validate native OAuth tokens."
env = "MISE_GITHUB_OAUTH_API_URL"
type = "String"
[github.oauth_auth_url]
default = "https://github.com/login"
description = "GitHub OAuth endpoint base URL for the native device flow."
docs = "Change it for a GitHub Enterprise host that supports device flow."
env = "MISE_GITHUB_OAUTH_AUTH_URL"
type = "String"
[github.oauth_cache_get]
default = ""
description = "Command that prints the native GitHub OAuth refresh tokens stored by github.oauth_cache_set."
docs = """
By default mise keeps the long-lived, rotating OAuth refresh token in
`github-oauth-tokens.toml` in its state directory, readable by anything running
as your user. Set this and
[`github.oauth_cache_set`](#github.oauth_cache_set) together to keep the refresh
token in a password manager or keychain instead; the file then holds only the
short-lived access token.
mise runs the command with the default inline shell
([`unix_default_inline_shell_args`](/configuration/settings.html#unix_default_inline_shell_args)
or
[`windows_default_inline_shell_args`](/configuration/settings.html#windows_default_inline_shell_args))
and reads the stored value from its stdout. It runs only when the access token
has to be refreshed, about once every eight hours, and when mise stores a new
token, not on every mise invocation. Empty output means nothing is
stored yet. If the command fails when mise needs to refresh, mise skips the refresh and
keeps the cached token, so a locked vault never costs you the session. While storing a new token, a failure counts as an empty store only if the
cache file still holds every refresh token, since many tools fail on an entry
that does not exist yet. The command gets no host, because one value holds the
tokens for every host. It is stopped after 60 seconds.
See [Keeping the refresh token out of the cache file](/dev-tools/github-tokens.html#keeping-the-refresh-token-out-of-the-cache-file).
"""
env = "MISE_GITHUB_OAUTH_CACHE_GET"
global_only = true
type = "String"
[github.oauth_cache_secure_enclave]
default = false
description = "Keep the native GitHub OAuth refresh token behind Touch ID in the macOS Secure Enclave."
docs = """
macOS only. mise seals the long-lived, rotating OAuth refresh token to the
Secure Enclave and keeps the sealed value in `github-oauth-tokens.sealed` in its
state directory; the cache file then holds only the short-lived access token.
Unsealing needs Touch ID, so mise asks for it only when the access token has to
be refreshed, about once every eight hours, and never on other invocations. The
sealed value works only on this Mac and stops working if the enrolled
fingerprints change, in which case `mise token github --oauth` authorizes again.
It needs a Mac with Touch ID and the Developer ID signed binary from mise's own
releases. Other builds, such as Homebrew, and machines without Touch ID warn and
keep the refresh token in the cache file. A failed or cancelled prompt never
discards the cached token: mise skips the refresh and tries again later. When
set, it takes precedence over
[`github.oauth_cache_get`](#github.oauth_cache_get) and
[`github.oauth_cache_set`](#github.oauth_cache_set).
See [Keeping the refresh token out of the cache file](/dev-tools/github-tokens.html#keeping-the-refresh-token-out-of-the-cache-file).
"""
env = "MISE_GITHUB_OAUTH_CACHE_SECURE_ENCLAVE"
global_only = true
type = "Bool"
[github.oauth_cache_set]
default = ""
description = "Command that stores the native GitHub OAuth refresh tokens, read from its stdin."
docs = """
The counterpart of [`github.oauth_cache_get`](#github.oauth_cache_get); set both
or neither. mise writes the complete value to the command's stdin, never to its
arguments, each time a refresh token is issued, because GitHub rotates it on
every refresh. If the command fails, mise keeps the refresh token in the cache
file instead of losing it, and warns.
```toml [~/.config/mise/config.toml]
[settings.github]
oauth_cache_get = "pass show mise/github-oauth"
oauth_cache_set = "pass insert -m -f mise/github-oauth"
```
"""
env = "MISE_GITHUB_OAUTH_CACHE_SET"
global_only = true
type = "String"
[github.oauth_client_id]
default = ""
description = "GitHub App client ID that turns on native OAuth device-flow tokens."
docs = """
With a client ID, mise creates short-lived GitHub App user access tokens through
GitHub's device flow, without a private key, client secret, personal access
token or credential helper. Run `mise token github --oauth` once to authorize;
mise caches the token, reuses it for GitHub API calls and refreshes it when it
can. See [Native GitHub OAuth](/dev-tools/github-tokens.html#native-github-oauth).
"""
env = "MISE_GITHUB_OAUTH_CLIENT_ID"
type = "String"
[github.oauth_copy_code]
description = "Copy the one-time device code to the clipboard during the native GitHub OAuth device flow."
docs = """
Only the device code is copied, never the token. mise uses `pbcopy` on macOS,
`clip.exe` on Windows and WSL, and `wl-copy`, `xclip` or `xsel` elsewhere. If
none is available the code is still printed.
When unset, mise asks whether to copy the code if it is running in a terminal.
Set it to `true` to always copy and `false` to never ask. Without a terminal,
nothing is copied unless it is `true`.
"""
env = "MISE_GITHUB_OAUTH_COPY_CODE"
optional = true
type = "Bool"
[github.oauth_export_env]
default = "GITHUB_TOKEN"
description = "Environment variable that mise exports the native GitHub OAuth token under; empty turns the export off."
docs = """
When [`github.oauth_client_id`](#github.oauth_client_id) is set and a cached or
refreshable token is available, mise exports the token under this variable
through `mise activate`, `mise env` and `mise exec`, so tools that read it, such
as `gh`, can use it. A value set in mise's `[env]` takes precedence; a value
already in your shell environment is replaced. Git credential helpers and Cargo
do not read this variable. Set it to `GH_TOKEN` for gh's preferred name.
"""
env = "MISE_GITHUB_OAUTH_EXPORT_ENV"
type = "String"
[github.oauth_open_browser]
default = true
description = "Open the verification page in your browser during the native GitHub OAuth device flow."
env = "MISE_GITHUB_OAUTH_OPEN_BROWSER"
type = "Bool"
[github.oauth_scopes]
default = ""
description = "OAuth scopes requested for native GitHub device-flow tokens."
docs = """
A GitHub App user access token gets its access from the app's permissions and
installations, so this usually stays empty.
"""
env = "MISE_GITHUB_OAUTH_SCOPES"
type = "String"
[github.slsa]
default = true
description = "Verify SLSA provenance for github backend tools that name a signer."
docs = """
Provenance is checked only for tools that set
[`slsa_signer_identity` and `slsa_signer_issuer`](/dev-tools/backends/github.html#slsa-signer-identity-and-slsa-signer-issuer),
and only while the global [`slsa`](/configuration/settings.html#slsa) setting is
`true`.
"""
env = "MISE_GITHUB_SLSA"
type = "Bool"
[github.use_git_credentials]
default = false
description = "Get GitHub tokens from your Git credential helpers with `git credential fill`."
docs = """
This reaches tokens kept by helpers such as the macOS Keychain or Windows
Credential Manager. mise tries it last, after the environment variables,
[`github.credential_command`](#github.credential_command), native GitHub OAuth,
`github_tokens.toml` and gh CLI tokens, and caches the result per host while it
runs. See
[Git credential helpers](/dev-tools/github-tokens.html#git-credential-helpers).
"""
env = "MISE_GITHUB_USE_GIT_CREDENTIALS"
type = "Bool"
[github_attestations]
default = true
description = "Verify GitHub artifact attestations for downloads whose publisher provides them."
docs = """
When `false`, the aqua and github backends skip attestation checks whatever
[`aqua.github_attestations`](#aqua.github_attestations) and
[`github.github_attestations`](#github.github_attestations) say. For
precompiled Python and Ruby, this is the default that
[`python.github_attestations`](#python.github_attestations) and
[`ruby.github_attestations`](#ruby.github_attestations) override.
"""
env = "MISE_GITHUB_ATTESTATIONS"
type = "Bool"
[github_relay.concurrency]
default = 8
description = "Maximum relayed GitHub requests that run at once, from 1 to 32; more requests fail instead of waiting."
docs = """
Applies to `mise ssh` and `mise bootstrap remote` sessions started with
`--github-relay-read-only`. See [Limits](/bootstrap/github-relay.html#limits).
"""
env = "MISE_GITHUB_RELAY_CONCURRENCY"
global_only = true
type = "Integer"
[github_relay.log_format]
default = "text"
description = "Format of GitHub relay request logs and the end-of-session summary."
docs = """
`--github-relay-log-format` overrides it for one session. See
[Logging](/bootstrap/github-relay.html#logging).
"""
enum = [
{ value = "text" },
{ value = "jsonl", description = "one JSON event per line" },
]
env = "MISE_GITHUB_RELAY_LOG_FORMAT"
global_only = true
type = "String"
[github_relay.log_requests]
default = false
description = "Log each relayed GitHub request, without credentials, on this machine's stderr."
docs = """
`--github-relay-log-requests` and `--github-relay-no-log-requests` override it
for one session. The setting never turns the relay on. See
[Logging](/bootstrap/github-relay.html#logging).
"""
env = "MISE_GITHUB_RELAY_LOG_REQUESTS"
global_only = true
type = "Bool"
[github_relay.max_duration]
default = "0s"
description = "How long a GitHub relay lends access; `0s` lasts until the session ends."
docs = """
`--github-relay-max-duration` overrides it for one session. See
[When access ends](/bootstrap/github-relay.html#when-access-ends).
"""
env = "MISE_GITHUB_RELAY_MAX_DURATION"
global_only = true
type = "Duration"
[github_relay.request_timeout]
default = "5m"
description = "Time limit for one relayed GitHub request, including streaming its response."
docs = """
Applies to `mise ssh` and `mise bootstrap remote` sessions started with
`--github-relay-read-only`. See [Limits](/bootstrap/github-relay.html#limits).
"""
env = "MISE_GITHUB_RELAY_REQUEST_TIMEOUT"
global_only = true
type = "Duration"
[gitlab.credential_command]
default = ""
description = "Command that prints a GitLab token on stdout."
docs = """
mise runs the command with the default inline shell
([`unix_default_inline_shell_args`](/configuration/settings.html#unix_default_inline_shell_args)
or
[`windows_default_inline_shell_args`](/configuration/settings.html#windows_default_inline_shell_args))
and uses its trimmed output as the token. The command receives
`MISE_CREDENTIAL_HOST`, the host that needs a token, so one command can serve
gitlab.com and self-managed GitLab hosts, and `MISE_CREDENTIAL_PROVIDER=gitlab`.
mise tries it right after the token environment variables; if it fails or
prints nothing, mise moves on to the next source. It does not need
[`gitlab.use_git_credentials`](#gitlab.use_git_credentials).
```toml [~/.config/mise/config.toml]
[settings.gitlab]
credential_command = 'op read "op://Private/GitLab Token/credential"'
```
See [Credential command](/dev-tools/github-tokens.html#credential-command) and
[Token priority](/dev-tools/github-tokens.html#token-priority).
"""
env = "MISE_GITLAB_CREDENTIAL_COMMAND"
global_only = true
type = "String"
[gitlab.glab_cli_tokens]
default = true
description = "Read GitLab tokens that the glab CLI stores in its `config.yml` file."
docs = """
See [CLI logins](/dev-tools/github-tokens.html#cli-logins) for where mise looks
for the file and [Token priority](/dev-tools/github-tokens.html#token-priority)
for when it is used.
"""
env = "MISE_GITLAB_GLAB_CLI_TOKENS"
type = "Bool"
[gitlab.use_git_credentials]
default = false
description = "Get GitLab tokens from your Git credential helpers with `git credential fill`."
docs = """
This reaches tokens kept by helpers such as the macOS Keychain or Windows
Credential Manager. mise tries it last, after the environment variables,
[`gitlab.credential_command`](#gitlab.credential_command),
`gitlab_tokens.toml` and glab CLI tokens, and caches the result per host while
it runs. See
[Git credential helpers](/dev-tools/github-tokens.html#git-credential-helpers).
"""
env = "MISE_GITLAB_USE_GIT_CREDENTIALS"
type = "Bool"
[gix]
default = true
description = "Clone Git repositories with the built-in gix library instead of running `git`."
docs = "mise runs the `git` command when both this and `libgit2` are `false`, and always inside a GitHub relay session started by `mise ssh`."
env = "MISE_GIX"
hide = true
type = "Bool"
[global_config_file]
description = "One file to use as the global config instead of the config files in `~/.config/mise`."
docs = """
When unset, mise reads `config.toml`, `conf.d/*.toml` and the other config
files in `~/.config/mise` (or `MISE_CONFIG_DIR`), and global writes such as
`mise use -g` go to `config.toml` there. When set, mise reads and writes only
this file.
"""
env = "MISE_GLOBAL_CONFIG_FILE"
env_only = true
optional = true
type = "Path"
[global_config_root]
default_docs = "`$HOME`"
description = "Directory used as `config_root` for the global config, such as for `{{config_root}}` in templates."
env = "MISE_GLOBAL_CONFIG_ROOT"
env_only = true
optional = true
type = "Path"
[go.default_packages_file]
default = "~/.default-go-packages"
deprecated = "Default go package files are deprecated. Use tool-level postinstall hooks for packages that should be installed into every go version, or use the go: backend for CLI tools."
deprecated_remove_at = "2027.11.0"
deprecated_warn_at = "2026.11.0"
description = "[deprecated] File listing Go packages to install with every Go version."
env = "MISE_GO_DEFAULT_PACKAGES_FILE"
type = "Path"
[go.download_mirror]
default = "https://dl.google.com/go"
description = "Base URL that mise downloads Go archives and their checksums from."
env = "MISE_GO_DOWNLOAD_MIRROR"
type = "String"
[go.repo]
default = "https://github.com/golang/go"
description = "Git repository mise lists Go versions from."
docs = """
mise reads the repository's `go*` tags to find Go versions when it does not get
them from the [versions host](/configuration/settings.html#use_versions_host);
set `use_versions_host = false` to always list from this repository. Downloads
come from [`go.download_mirror`](#go.download_mirror).
"""
env = "MISE_GO_REPO"
type = "Url"
[go.set_gobin]
description = "Set `GOBIN` so `go install` puts binaries in the active Go version's directory."
docs = """
When unset, mise sets `GOBIN` to the active Go version's `bin` directory unless
`GOBIN` is already set in your environment. `true` always sets it, replacing
your `GOBIN`. `false` never sets it, so `go install` uses your own `GOBIN` or
Go's default, `${GOPATH:-$HOME/go}/bin`.
"""
env = "MISE_GO_SET_GOBIN"
optional = true
type = "Bool"
[go.set_gopath]
deprecated = "Set GOPATH in [env] instead. When true, this setting still sets GOPATH to the Go install's `packages` directory."
description = "[deprecated] Set `GOPATH` to the `packages` directory inside the active Go install."
env = "MISE_GO_SET_GOPATH"
type = "Bool"
[go.set_goroot]
default = true
description = "Set `GOROOT` to the active Go version's install directory."
env = "MISE_GO_SET_GOROOT"
type = "Bool"
[go.skip_checksum]
description = "Skip SHA-256 verification of Go downloads."
env = "MISE_GO_SKIP_CHECKSUM"
type = "Bool"
[go_default_packages_file]
deprecated = "Use go.default_packages_file instead."
description = "File listing Go packages to install with every Go version."
hide = true
optional = true
type = "Path"
[go_download_mirror]
deprecated = "Use go.download_mirror instead."
description = "Base URL that mise downloads Go archives and their checksums from."
hide = true
optional = true
type = "String"
[go_repo]
deprecated = "Use go.repo instead."
description = "Git repository mise lists Go versions from."
hide = true
optional = true
type = "Url"
[go_set_gobin]
deprecated = "Use go.set_gobin instead."
description = "Set `GOBIN` so `go install` puts binaries in the active Go version's directory."
hide = true
optional = true
type = "Bool"
[go_set_gopath]
deprecated = "Set GOPATH in [env] instead."
description = "[deprecated] Set `GOPATH` to the `packages` directory inside the active Go install."
hide = true
optional = true
type = "Bool"
[go_set_goroot]
deprecated = "Use go.set_goroot instead."
description = "Set `GOROOT` to the active Go version's install directory."
hide = true
optional = true
type = "Bool"
[go_skip_checksum]
deprecated = "Use go.skip_checksum instead."
description = "Skip SHA-256 verification of Go downloads."
hide = true
optional = true
type = "Bool"
[gpg_verify]
description = "Verify OpenPGP signatures of Node.js and Swift downloads."
docs = """
Sets the default for [`node.gpg_verify`](#node.gpg_verify) and
[`swift.gpg_verify`](#swift.gpg_verify); a tool's own setting takes precedence.
mise checks signatures itself, so no `gpg` binary is needed. When unset, mise
verifies the signed `SHASUMS256.txt` whenever [`node.verify`](#node.verify)
checks a Node.js download, and Swift downloads on Linux.
Set to `false` to skip both.
"""
env = "MISE_GPG_VERIFY"
optional = true
type = "Bool"
[history.allow_plaintext_history]
default = false
description = "Allow publishing or applying history that holds plaintext copies of files now marked for encryption, or publishing versions that look like they contain secrets."
docs = """
By default, the history watcher, `mise dot sync` and `mise dot pull` refuse to
publish or apply history in which a file now marked for encryption was once
saved in plain text, or to publish saved versions with lines that look like
secrets, such as `export API_TOKEN=...`. With `true`, they skip those checks, so
those older versions can reach this machine or the setup repository. New saves
still follow each file's encryption policy. For a single publish, run
`mise dot sync --allow-plaintext-history` instead. See
[Allow plaintext history](/dotfiles/encryption.html#allow-plaintext-history).
"""
env = "MISE_HISTORY_ALLOW_PLAINTEXT_HISTORY"
global_only = true
type = "Bool"
[history.describe_command]
default = ""
description = "Command, such as an AI agent, that writes the description of each checkpoint the history watcher saves."
docs = """
mise saves the checkpoint first, then runs the command once with a JSON object
on stdin: `uuid`, `trigger`, the computed `description`, the changed paths
(`added`, `modified`, `removed`) and a unified `diff` of changed unencrypted
files, cut at 64 KiB. The line the command prints, up to 200 characters,
replaces the computed description. If the command fails, prints nothing, or
runs longer than 30 seconds, the computed description stays. Leave it empty to
keep computed descriptions.
The diff is sent to the command. Excluded files are never named, and encrypted
contents are never sent. See
[Descriptions from an agent](/dotfiles/history.html#descriptions-from-an-agent).
"""
env = "MISE_HISTORY_DESCRIBE_COMMAND"
global_only = true
type = "String"
[history.enabled]
default = true
description = "Record Git checkpoints of tracked files around bootstrap operations and on explicit saves."
docs = """
Once you track files, or history already exists, `mise bootstrap` and
`mise bootstrap <part> apply` record a checkpoint before and after they change
anything, and `mise dot save` records one on demand. Dry runs never record.
Checkpoints live in `$MISE_STATE_DIR/history/repo.git`; browse them with
`mise dot history`.
Set to `false` to stop recording; existing checkpoints are kept. See
[Saving](/dotfiles/history.html#saving).
"""
env = "MISE_HISTORY_ENABLED"
type = "Bool"
[history.fetch_interval]
default = "15m"
description = "How often the history watcher fetches from the setup repository."
docs = """
Values below one second count as one second. To stop automatic fetching, set
[`history.sync`](#history.sync) to `manual`.
"""
env = "MISE_HISTORY_FETCH_INTERVAL"
type = "Duration"
[history.notify]
default = true
description = "Show a desktop notification when a sync conflict pauses sharing."
docs = """
mise notifies once, when conflicts first pause sharing for the setup; retries
stay silent until sharing recovers. Other problems, such as a watcher that
cannot save, appear only in `mise doctor` and `mise dot status`. A missing or
failing notifier never holds up history or sync.
Linux needs `notify-send`. On macOS, the first notification asks for
permission, so mise does not appear in System Settings > Notifications until
then; run `mise dot notify` to send a test and get the prompt now. Unofficial
macOS builds, such as Homebrew's, never show notifications and warn when you
connect a setup repository. Other platforms only log the conflict. See
[Conflict notifications](/dotfiles/sync.html#conflict-notifications).
"""
env = "MISE_HISTORY_NOTIFY"
type = "Bool"
[history.sync]
default = "sync"
description = "What the history watcher shares with a connected setup repository on its own."
docs = """
`mise dot origin set` asks for a mode when you connect a repository, or takes it
from `--sync`. In `sync` mode, mise publishes at most every
[`history.sync_interval`](#history.sync_interval) after a save and fetches every
[`history.fetch_interval`](#history.fetch_interval); failures back off from one
minute up to an hour, and local saves continue. A conflict pauses publishing
and applying for the whole setup until you resolve it, while local saves and
fetches go on. `mise dot sync` and `mise dot pull` run on request in every
mode, but nothing is ever published in `fetch-only` mode.
Applying incoming changes never runs `mise bootstrap`, installs packages or
renders templates. When incoming configuration changes what this machine
declares, `mise dot status` tells you to run `mise bootstrap`. See
[Choose a sync mode](/dotfiles/sync.html#choose-a-sync-mode).
"""
enum = [
{ value = "sync", description = "publish saves, fetch periodically and apply incoming changes" },
{ value = "fetch-only", description = "fetch periodically and never publish; apply only when you run `mise dot pull`" },
{ value = "manual", description = "no automatic network activity; `mise dot sync` publishes and fetches, and `mise dot pull` applies, when you run them" },
]
env = "MISE_HISTORY_SYNC"
type = "String"
[history.sync_interval]
default = "5m"
description = "Minimum time between automatic publishes to the setup repository after a save."
env = "MISE_HISTORY_SYNC_INTERVAL"
type = "Duration"
[history.watch.debounce]
default = "2s"
description = "How long a changed file must stay unchanged before the history watcher saves it."
docs = """
A file that keeps changing gets a longer interval of its own, up to
[`history.watch.max_interval`](#history.watch.max_interval), without delaying
other files.
"""
env = "MISE_HISTORY_WATCH_DEBOUNCE"
type = "Duration"
[history.watch.max_interval]
default = "24h"
description = "Longest save interval the history watcher uses for a file that changes constantly."
docs = """
A file that keeps being rewritten has its own save interval doubled, up to this
value, so it is still saved, ever more rarely; other files are never delayed.
A settled file is saved promptly again, and a sustained quiet period resets its
interval. mise never excludes a file or switches it to manual saving on its
own: exclude logs, caches and databases with `mise dot exclude`, or track a
configuration file that changes constantly with `autosave = false` and save it
with `mise dot save`. See
[Adaptive scheduling](/dotfiles/reference.html#adaptive-scheduling).
"""
env = "MISE_HISTORY_WATCH_MAX_INTERVAL"
type = "Duration"
[history.watch.reconcile]
default = "10m"
description = "How often the history watcher rescans all tracked files for changes it missed."
docs = """
Set to `0s` to turn off periodic rescans; the watcher still rescans at startup
and when configuration changes.
"""
env = "MISE_HISTORY_WATCH_RECONCILE"
type = "Duration"
[hook_env.cache_ttl]
default = "0s"
description = "How long the shell hook reuses its last config file check, for slow filesystems such as NFS."
docs = """
The shell hook checks config files at every prompt, which can be slow on a
network filesystem with a cold cache. A positive value such as `5s` reuses the
last check for that long; `0s` checks every time. While a check is reused, a
newly created config file goes unnoticed until the time runs out;
`mise hook-env --force` skips the cache. See
[Slow shell prompts](/troubleshooting.html#slow-shell-prompts).
"""
env = "MISE_HOOK_ENV_CACHE_TTL"
type = "Duration"
[hook_env.chpwd_only]
default = false
description = "Run the shell hook's full config check only when you change directories, not at every prompt."
docs = """
This cuts filesystem work on slow filesystems such as NFS. Changes to config
files take effect after your next `cd`; `mise hook-env --force` runs a full
check. See [Slow shell prompts](/troubleshooting.html#slow-shell-prompts).
"""
env = "MISE_HOOK_ENV_CHPWD_ONLY"
type = "Bool"
[http_download_timeout]
default = "30m"
description = "Total time allowed to download one file, including retries."
docs = """
Covers every attempt and backoff delay; [`http_timeout`](#http_timeout)
separately catches stalled connections. When the server supports byte ranges
and sends a strong `ETag` or `Last-Modified` value, mise keeps a partial
download and resumes it on the next attempt, even in a later run; otherwise the
download starts over. Changing the URL or request headers discards the partial
file.
The same limit bounds reading the body of a response that mise parses instead
of saving, such as a checksum file or a version list, so a server that sends it
a byte at a time cannot hold a command forever.
"""
env = "MISE_HTTP_DOWNLOAD_TIMEOUT"
type = "Duration"
[http_retries]
default = 3
description = "Number of retries after a transient HTTP failure."
docs = """
mise retries only transient errors: HTTP 5xx, 408 (Request Timeout), 429 (Too
Many Requests) and network failures such as a refused connection, a timeout or
a dropped response body. Other 4xx responses, such as 404, are not retried.
Retries back off with jitter, roughly 200ms, 1s, 4s and 15s. Set to `0` to turn
retries off.
Commands that prefer offline data, including shims and shell activation, never
retry remote lookups: they make one attempt when cached data is not enough, then
fail or fall back. Downloading a tool they install, such as the first
`mise exec`, still retries. When a retry succeeds, mise logs a warning with the original error.
"""
env = "MISE_HTTP_RETRIES"
type = "Integer"
[http_timeout]
default = "30s"
description = "Timeout for connecting or waiting between reads during HTTP requests."
docs = """
The read timer restarts whenever data arrives, so a long download is limited by
[`http_download_timeout`](#http_download_timeout) instead.
"""
env = "MISE_HTTP_TIMEOUT"
type = "Duration"
[idiomatic_version_file]
deprecated = "No longer has any effect: idiomatic version files are off unless enabled per tool with idiomatic_version_file_enable_tools."
description = "[deprecated] No effect; enable idiomatic version files per tool with `idiomatic_version_file_enable_tools`."
env = "MISE_IDIOMATIC_VERSION_FILE"
hide = true
optional = true
type = "Bool"
[idiomatic_version_file_disable_files]
default = []
description = "Idiomatic version files to ignore for one tool, as `tool:filename` pairs."
docs = """
Turns off one file for one tool without disabling that tool's other version
files or other tools that read the same file. To keep `.nvmrc` but stop node
from reading `devEngines.runtime` in `package.json`:
```sh
mise settings add idiomatic_version_file_disable_files node:package.json
```
"""
env = "MISE_IDIOMATIC_VERSION_FILE_DISABLE_FILES"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[idiomatic_version_file_disable_tools]
default = []
deprecated = "This has been replaced with the idiomatic_version_file_enable_tools setting."
description = "[deprecated] No effect; idiomatic version files are off unless enabled with `idiomatic_version_file_enable_tools`."
env = "MISE_IDIOMATIC_VERSION_FILE_DISABLE_TOOLS"
hide = true
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[idiomatic_version_file_enable_tools]
default = []
description = "Tools that read idiomatic version files such as `.node-version` or `.ruby-version`."
docs = """
Idiomatic version files are off by default. To turn them on for Node.js and
Python:
```sh
mise settings add idiomatic_version_file_enable_tools node
mise settings add idiomatic_version_file_enable_tools python
```
See [Idiomatic version files](/dev-tools/versions.html#idiomatic-version-files).
"""
env = "MISE_IDIOMATIC_VERSION_FILE_ENABLE_TOOLS"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[idiomatic_version_file_ignore_minimum_versions]
default = false
description = "Ignore idiomatic version file fields that only declare a minimum compatible version."
docs = """
Affects `go.mod`'s `go X.Y` line (a `toolchain goX.Y.Z` line, or an exact
`go X.Y.Z` line with no `toolchain` line, is still read) and
`CMakeLists.txt`'s `cmake_minimum_required`. mise still reads those minimums
with a deprecation warning; this setting opts into the final behavior now and
silences the warning. In mise 2026.11.0 that behavior becomes unconditional and
this setting is removed. See
[Which fields mise reads](/dev-tools/versions.html#which-fields-mise-reads).
"""
env = "MISE_IDIOMATIC_VERSION_FILE_IGNORE_MINIMUM_VERSIONS"
hide = true
type = "Bool"
[ignored_config_paths]
default = []
description = "Config files and directories mise does not load."
docs = """
Entries are paths or glob patterns, including `**`. A path without glob
characters also matches everything under it. Relative paths in a `.miserc.toml`
resolve from the directory that holds it, and relative paths in
`MISE_IGNORED_CONFIG_PATHS` from the directory where you run mise.
Commands that act on every tracked config (`mise prune`, `mise ls --prunable`
and the stale-version check in `mise upgrade`) honor only the environment
variable and the global and system `miserc.toml` files, so a project's
`.miserc.toml` cannot hide other projects' configs from them. The same applies
to global and system config: a project's `.miserc.toml` cannot ignore it.
`mise settings` and `mise settings add` refuse this setting, because mise
reads it before config files load; put it in a `.miserc.toml` file or the
environment variable instead.
"""
env = "MISE_IGNORED_CONFIG_PATHS"
parse_env = "list_by_os_path_separator"
rc = true
rust_type = "BTreeSet<PathBuf>"
type = "ListPath"
[install_before]
deprecated = "Use minimum_release_age instead."
deprecated_remove_at = "2027.10.0"
deprecated_warn_at = "2026.10.0"
description = "[deprecated] Install only versions released before this date; use `minimum_release_age` instead."
env = "MISE_INSTALL_BEFORE"
hide = true
optional = true
type = "String"
[install_layout]
default_docs = "`identity` on Windows with `experimental = true`, otherwise `legacy`"
description = "[experimental] Name installations by what they are (`identity`) instead of `installs/<tool>/<version>` (`legacy`)."
docs = """
With `identity`, each installation goes into an `installs/<label>-<hash>/`
directory named by its identity (backend, version, platform and
install-affecting options), and `installs/<tool>/<version>` stays as a link to
it. Shorthands such as `age` and `aqua:FiloSottile/age` then share one install,
and variants of one version that differ in an install-affecting option can
coexist. Existing installs stay where they are and keep working.
It requires `experimental = true`. On Windows, `experimental = true` turns it
on by itself; set `install_layout = "legacy"` to keep the legacy layout there.
On other platforms, set both:
```toml
[settings]
experimental = true
install_layout = "identity"
```
See [Identity install layout](/dev-tools/install-layout.html) for what changes
and what does not.
"""
enum = ["legacy", "identity"]
env = "MISE_INSTALL_LAYOUT"
optional = true
type = "String"
[ipv4_only]
default = false
description = "Connect to remote hosts over IPv4 only."
docs = """
Use it when a host answers wrongly over IPv6 while IPv4 works, for example
`dl.google.com` returning `404 Not Found` for a Go download, or the Sigstore
trust root failing to load during attestation verification. Without it mise
follows the system resolver, which usually prefers IPv6 on a dual-stack machine.
It applies to the connections mise makes with its own HTTP client: downloads,
version lookups, GitHub API calls, attestation verification, vfox plugins and
the GitHub relay. Programs mise runs, such as `git`, `npm` or a tool's
installer, follow the system, and so does the package manager embedded in the
`npm:` backend. For those, prefer IPv4 system-wide, for example with
`precedence ::ffff:0:0/96 100` in `/etc/gai.conf`.
A host with no IPv4 address cannot be reached while this is on.
"""
env = "MISE_IPV4_ONLY"
type = "Bool"
[java.shorthand_vendor]
default = "temurin"
description = "Vendor used for a Java version without a vendor prefix, such as `java@21`."
docs = """
Versions without a vendor prefix, such as `java@21`, `java@lts` or
`java@latest`, install this vendor's builds. The default is `temurin` (Eclipse
Temurin), which keeps publishing quarterly updates for long-term-support
releases.
Earlier versions of mise defaulted to `openjdk`. jdk.java.net publishes OpenJDK
builds only until the next feature release, so with that vendor `java@21` stays
on 21.0.2. To keep the old behavior, set this to `openjdk`, or request
`openjdk-21` explicitly. Temurin has no builds of Java 9, 10 or 12 through 15;
request those with an `openjdk-` prefix.
Installed versions are not changed: a version such as `21.0.2` installed from
OpenJDK keeps resolving to that OpenJDK build when the current vendor does not
publish it. A lockfile entry records the vendor setting that resolved it, so an
entry written with `openjdk` matches only while this setting is `openjdk`. With
another vendor, `mise install --locked` reports that the tool is not in the
lockfile. Plain `mise lock` locks the installed OpenJDK build again under the
new setting; run `mise lock --bump java` to lock the new vendor's build instead.
```toml
[settings]
java.shorthand_vendor = "openjdk"
```
"""
env = "MISE_JAVA_SHORTHAND_VENDOR"
type = "String"
[jobs]
default = 8
description = "How many jobs to run concurrently such as tool installs. Values below 1 are treated as 1."
env = "MISE_JOBS"
rust_type = "usize"
type = "Integer"
[legacy_version_file]
default = true
deprecated = "No longer has any effect: idiomatic version files are off unless enabled per tool with idiomatic_version_file_enable_tools."
description = "[deprecated] No effect; enable idiomatic version files per tool with `idiomatic_version_file_enable_tools`."
env = "MISE_LEGACY_VERSION_FILE"
hide = true
type = "Bool"
[legacy_version_file_disable_tools]
default = []
deprecated = "No longer has any effect: idiomatic version files are off unless enabled per tool with idiomatic_version_file_enable_tools."
description = "[deprecated] No effect; idiomatic version files are off unless enabled with `idiomatic_version_file_enable_tools`."
env = "MISE_LEGACY_VERSION_FILE_DISABLE_TOOLS"
hide = true
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[libc]
description = "Libc build to install on Linux when a tool publishes both glibc and musl builds."
docs = """
When unset, mise uses musl builds on a detected musl host, and leaves a glibc
host unqualified rather than pinned to glibc, so a backend that picks assets by
name can still choose a musl build there. Set it to require the glibc build, for
example when a package's musl build misbehaves:
```toml
[settings]
libc = "glibc"
```
`gnu` is accepted as an alias for `glibc`.
"""
enum = ["glibc", "gnu", "musl"]
env = "MISE_LIBC"
optional = true
type = "String"
[libgit2]
default = true
description = "Clone Git repositories with the built-in gix library instead of running `git`; same as `gix`."
docs = "mise runs the `git` command when both this and `gix` are `false`, and always inside a GitHub relay session started by `mise ssh`."
env = "MISE_LIBGIT2"
hide = true
type = "Bool"
[locked]
default = false
description = "Require tool versions and download URLs to come from the lockfile."
docs = """
Resolves tools only from lockfile entries, instead of looking versions and URLs
up through the GitHub API or a registry. A tool with no matching entry is an
error, both for installs and for lookups such as `mise which`, even when the
tool is already installed. Backends that lock download URLs must have one for
the current platform, and recorded dependency graphs must be present and match
their digest; backends that do not lock URLs, such as `cargo`, `go`, `gem` and
`asdf`, need only the version. Installs in this mode do not update lockfiles.
Same as passing `--locked`.
Use it in CI to avoid API rate limits and to catch an incomplete lockfile early;
create the entries with `mise lock`. Locked mode reads existing lockfiles even
when [`lockfile`](#lockfile) is unset, and fails with `lockfile = false`. It
does not make installs offline: downloads, provenance checks and
private-repository API downloads can still need network access and
authentication. [`locked_scopes`](#locked_scopes) limits which config scopes it
applies to. See
[Strict lockfile mode](/dev-tools/mise-lock.html#strict-lockfile-mode).
"""
env = "MISE_LOCKED"
type = "Bool"
[locked_scopes]
default = ["global", "project", "system"]
description = "Config scopes where invocation-wide locked mode is enforced."
docs = """
Limits invocation-wide locked mode (`--locked`, `MISE_LOCKED=1` or
[`locked = true`](#locked)) to tools from these config scopes; `global` is your
user config. For example, a distribution that declares rolling tools in system
config can exclude them while keeping strict locking for project and user
tools:
```toml
[settings]
locked_scopes = ["project", "global"]
```
Tools given as command arguments or through environment variables have no
config scope, so invocation-wide locked mode always applies to them. A config
root's `[tool_config] locked = true` applies even when its scope is not listed.
Excluding a scope relaxes locked mode there; mise still reads existing
lockfiles. Project config cannot set this, so a repository cannot weaken your
locked-mode policy.
"""
enum = ["project", "global", "system"]
env = "MISE_LOCKED_SCOPES"
global_only = true
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[locked_verify_provenance]
default = false
description = "Re-verify provenance at install time even when the lockfile already records it."
docs = """
By default, when a lockfile entry has both a checksum and a provenance type,
`mise install` trusts the lockfile and does not verify provenance (SLSA,
cosign, minisign or GitHub artifact attestations) again, which saves API calls.
With `true`, mise verifies every time, at the cost of more network requests.
[`paranoid`](#paranoid) turns it on.
"""
env = "MISE_LOCKED_VERIFY_PROVENANCE"
type = "Bool"
[lockfile]
description = "Create, read and update `mise.lock` lockfiles for tool versions."
docs = """
A lockfile records the exact version, download URLs and checksums resolved for
each tool, so every machine installs the same build even when `mise.toml` asks
for `node = "24"`.
- `true` in a config file: create, read and update lockfiles for project
config.
- unset: read and update lockfiles that exist, but create none; run `mise lock`
to create one. `MISE_LOCKFILE=1` behaves the same way.
- `false`: ignore lockfiles. [`locked`](#locked) mode fails with this value.
A lockfile normally sits next to its config file and is named `mise.lock`, or
`mise.local.lock`, `mise.<env>.lock` or `mise.<env>.local.lock` for local and
environment config; `.config/mise/config.toml` uses `.config/mise/mise.lock`,
and fragments in `conf.d` share the lockfile of the directory that holds
`conf.d`. Global lockfiles are created only by `mise lock --global`. See
[Lockfile](/dev-tools/mise-lock.html) and
[which lockfile a tool uses](/dev-tools/mise-lock.html#which-lockfile-a-tool-uses).
"""
env = "MISE_LOCKFILE"
optional = true
type = "Bool"
[lockfile_auto_prune]
default = true
description = "Remove lockfile tools that are absent from the active configuration."
docs = """
By default, a full `mise lock` removes entries for tools that the active
configuration does not declare, which keeps a lockfile in step with one
configuration. Set this to `false` for a lockfile shared by
[config environments](/configuration/environments.html) that declare different
tools:
```toml
[settings]
lockfile_auto_prune = false
```
It changes only which tools are kept: configured tools still refresh, and their
stale versions, option variants and native dependency graphs are still removed.
It applies in both [`lockfile_mode`](#lockfile_mode) values and to
`mise lock --global`. A filtered command such as `mise lock node` keeps tools
outside its filter anyway.
"""
env = "MISE_LOCKFILE_AUTO_PRUNE"
type = "Bool"
[lockfile_mode]
default = "generate"
description = "How lockfiles are written: rebuilt from the current requests, or entry by entry."
docs = """
Neither mode creates lockfiles; set [`lockfile = true`](#lockfile) or run
`mise lock`. See
[Complete lockfile generation](/dev-tools/mise-lock-reference.html#complete-lockfile-generation).
"""
enum = [
{ value = "merge", description = "update entries as tools are installed" },
{ value = "generate", description = "rebuild the whole lockfile from the current requests, reusing unchanged entries, and lock other platforms during installs" },
]
env = "MISE_LOCKFILE_MODE"
type = "String"
[lockfile_platforms]
description = "Platforms to resolve lockfile URLs and checksums for."
docs = """
Applies to `mise lock` without `--platform` and to automatic locking during
`mise install` and `mise use`. The current platform is always added. Listing
only the platforms you use keeps lockfiles smaller and installs faster. An
explicit `mise lock --platform` ignores this setting.
```toml
[settings]
lockfile_platforms = ["macos-arm64", "linux-x64"]
```
When unset, mise keeps the platforms already recorded in the lockfile, and
automatic locking also adds the current platform. A new lockfile gets
`linux-x64`, `linux-x64-musl`, `linux-arm64`, `linux-arm64-musl`, `macos-x64`,
`macos-arm64` and `windows-x64`, plus the current platform. Write platforms as
`os-arch` or `os-arch-qualifier`, such as `linux-x64-musl`.
"""
env = "MISE_LOCKFILE_PLATFORMS"
optional = true
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[log_level]
default = "info"
description = "Log level for mise's own output."
enum = ["trace", "debug", "info", "warn", "error"]
env = "MISE_LOG_LEVEL"
hide = true
type = "String"
[minimum_release_age]
default_docs = "24h"
description = "Skip versions published more recently than this duration or date."
docs = """
Holds back newly published versions to limit supply-chain risk. Accepts a
duration such as `7d`, `6mo` or `1y`, or a cutoff date such as `2024-06-01` or
`2024-06-01T12:00:00Z`; `0s` turns the delay off.
```toml
[settings]
minimum_release_age = "7d"
```
The `24h` default applies to every backend, except for tools in
[`minimum_release_age_excludes`](#minimum_release_age_excludes). A backend can
only hold back versions it knows a release date for. When mise installs a
version that has none, it warns that the cutoff could not be checked; see
[Which backends have a default](/security.html#which-backends-have-a-default).
A value you set applies to every backend.
The cutoff applies when mise resolves a version request such as `node@22` or
`latest`, for backends that report release dates. Exact versions such as
`node@22.5.0`, and versions recorded in `mise.lock`, are not filtered. The
`npm:` and `pypi:` backends also pass the cutoff to the package manager for
unpinned transitive dependencies. Override it for one tool with the
`minimum_release_age` tool option, or for one command with
`--minimum-release-age`. See
[Minimum release age](/security.html#minimum-release-age).
"""
env = "MISE_MINIMUM_RELEASE_AGE"
optional = true
type = "String"
[minimum_release_age_excludes]
default = []
description = "Tools and backends that the configured and default `minimum_release_age` do not apply to."
docs = """
An entry matches a backend wildcard such as `npm:*`, a registry short name such
as `trivy`, or a full backend ID such as `aqua:aquasecurity/trivy`:
```toml
[settings]
minimum_release_age = "7d"
minimum_release_age_excludes = ["trivy", "npm:*"]
```
A tool's own `minimum_release_age` option and `--minimum-release-age` still
apply to excluded tools. Lists from several config files are combined, so a
project can add exclusions without repeating global ones;
`MISE_MINIMUM_RELEASE_AGE_EXCLUDES` replaces the combined list.
"""
env = "MISE_MINIMUM_RELEASE_AGE_EXCLUDES"
merge = "append_unique"
parse_env = "list_by_comma"
type = "ListString"
[netrc]
default = true
description = "Use a netrc file for HTTP Basic authentication."
docs = """
mise reads credentials from the netrc file and sends them to matching hosts with
HTTP Basic authentication, such as a private Artifactory or Nexus server. The
file is `~/.netrc` on Unix and macOS. On Windows, mise looks for
`%USERPROFILE%\\_netrc`, then `%USERPROFILE%\\.netrc`. Use
[`netrc_file`](#netrc_file) for another location.
```text
machine artifactory.example.com
login myuser
password mytoken
```
"""
env = "MISE_NETRC"
type = "Bool"
[netrc_file]
description = "Path of the netrc file to use instead of `~/.netrc` (`%USERPROFILE%\\_netrc` on Windows)."
env = "MISE_NETRC_FILE"
optional = true
type = "Path"
[no_env]
description = "Do not load environment variables from config files."
docs = """
Same as the global `--no-env` flag. See
[Environment variables](/environments/#no-env).
"""
env = "MISE_NO_ENV"
optional = true
type = "Bool"
[no_hooks]
description = "Do not execute hooks from config files."
docs = "Same as the global `--no-hooks` flag. See [Hooks](/hooks.html#disable-hooks)."
env = "MISE_NO_HOOKS"
optional = true
type = "Bool"
[node.apply_patches]
description = "Patch files or URLs to apply to the Node.js source before building it."
docs = """
List one patch file or URL per line. mise applies them to the extracted source
before `./configure` runs. They apply only to source builds: with
[`node.compile = true`](#node.compile), or when no precompiled build exists for
the version and mise compiles instead. When mise installs a precompiled build,
it warns that the patches were skipped.
"""
env = "MISE_NODE_APPLY_PATCHES"
optional = true
type = "String"
[node.cflags]
description = "Extra `CFLAGS` for compiling Node.js, for example to replace `-O3`."
docs = "When unset, mise uses `NODE_CFLAGS` from the environment."
env = "MISE_NODE_CFLAGS"
optional = true
type = "String"
[node.compile]
description = "Compile Node.js from source instead of using a precompiled build."
docs = """
`false` uses only precompiled builds and fails when none exists. When unset,
[`all_compile`](/configuration/settings.html#all_compile) decides; if that is
unset too, mise uses a precompiled build when one exists and compiles
otherwise. See [Building from source](/lang/node.html#building-from-source).
"""
env = "MISE_NODE_COMPILE"
optional = true
type = "Bool"
[node.concurrency]
default_docs = "physical CPU cores, or unset when `node.ninja` is on"
description = "Number of parallel jobs (`make -j`) when compiling Node.js."
docs = "Values below 1 count as 1. With [`node.ninja`](#node.ninja), ninja picks the job count when this is unset."
env = "MISE_NODE_CONCURRENCY"
optional = true
type = "Integer"
[node.configure_opts]
description = "Extra arguments for `./configure` when compiling Node.js."
docs = "When unset, mise uses `NODE_CONFIGURE_OPTS` from the environment."
env = "MISE_NODE_CONFIGURE_OPTS"
optional = true
type = "String"
[node.corepack]
description = "Run `corepack enable` after installing a Node.js version, so `yarn` and `pnpm` go through Corepack."
docs = """
Applies to Node.js versions that include Corepack. When
[`node.npm_shim`](#node.npm_shim) is off, mise also runs `corepack enable npm`.
mise installs package managers itself, so Corepack is optional; see
[Corepack](/lang/node.html#corepack).
"""
env = "MISE_NODE_COREPACK"
type = "Bool"
[node.default_packages_file]
default_docs = "~/.default-npm-packages"
deprecated = "Default npm package files are deprecated. Use tool-level postinstall hooks for packages that should be installed into every node version, or use the npm: backend for CLI tools."
deprecated_remove_at = "2027.11.0"
deprecated_warn_at = "2026.11.0"
description = "[deprecated] File listing npm packages to install globally into each new Node.js version."
docs = """
One package per line, with an optional version:
```text
typescript@latest
@types/node@^24
```
When this is unset, mise uses `NODE_DEFAULT_PACKAGES_FILE`, then
`~/.default-nodejs-packages` or `~/.default-node-packages` if one exists, and
otherwise `~/.default-npm-packages`. See
[Default packages file](/lang/node.html#default-node-packages).
"""
env = "MISE_NODE_DEFAULT_PACKAGES_FILE"
optional = true
type = "Path"
[node.flavor]
description = "Linux build flavor of Node.js to download, such as `musl` or `glibc-217`."
docs = """
Flavors come from the [unofficial builds](https://unofficial-builds.nodejs.org/)
project, so also set [`node.mirror_url`](#node.mirror_url) to
`https://unofficial-builds.nodejs.org/download/release/`. `musl` is the
exception: with the default mirror, mise downloads it from the unofficial
builds by itself, and it selects `musl` automatically on musl hosts. See
[Unofficial builds](/lang/node.html#unofficial-builds).
"""
env = "MISE_NODE_FLAVOR"
optional = true
type = "String"
[node.gpg_verify]
default_docs = "true"
description = "Check the OpenPGP signature of the `SHASUMS256.txt` file that `node.verify` checks downloads against."
docs = """
mise checks the signature itself, so `gpg` does not need to be installed. It
runs only when [`node.verify`](#node.verify) is on, for installs and for the
checksums [`mise lock`](/cli/lock.html) records. A missing `.sig` fails the
check, except on unofficial-builds, which signs nothing. Set to `false` to skip
the check, for example for a mirror that does not copy the signatures or for
one of the few early releases (such as 4.0.0 and 5.12.0) that never published
one. The global
[`gpg_verify`](/configuration/settings.html#gpg_verify) setting sets the
default.
"""
env = "MISE_NODE_GPG_VERIFY"
optional = true
type = "Bool"
[node.make]
description = "Command to run instead of `make` when compiling Node.js, such as `gmake`."
docs = "Used for both the build and `make install`."
env = "MISE_NODE_MAKE"
optional = true
type = "String"
[node.make_install_opts]
description = "Extra arguments for `make install` when compiling Node.js."
docs = "When unset, mise uses `NODE_MAKE_INSTALL_OPTS` from the environment."
env = "MISE_NODE_MAKE_INSTALL_OPTS"
optional = true
type = "String"
[node.make_opts]
description = "Extra arguments for `make` when compiling Node.js."
docs = "When unset, mise uses `NODE_MAKE_OPTS` from the environment."
env = "MISE_NODE_MAKE_OPTS"
optional = true
type = "String"
[node.mirror_url]
default_docs = "https://nodejs.org/dist/"
description = "Base URL that mise downloads Node.js archives and their `SHASUMS256.txt` checksums from."
docs = """
When unset, mise uses `NODE_BUILD_MIRROR_URL` from the environment, then the
default. With the default URL, musl builds come from the unofficial builds site
instead. See [Unofficial builds](/lang/node.html#unofficial-builds).
"""
env = "MISE_NODE_MIRROR_URL"
optional = true
type = "Url"
[node.ninja]
default_docs = "`true` when `ninja` is on `PATH`"
description = "Build Node.js with ninja instead of make when compiling from source."
docs = """
With ninja, and [`node.concurrency`](#node.concurrency) unset, ninja chooses
how many jobs to run in parallel.
"""
env = "MISE_NODE_NINJA"
optional = true
type = "Bool"
[node.nodenv_root]
default = "~/.nodenv"
description = "Root directory of nodenv, which `mise sync node --nodenv` imports Node.js versions from."
env = "NODENV_ROOT"
type = "Path"
[node.npm_shim]
default = true
description = "Wrap each Node.js version's `npm` so that `npm install -g` runs `mise reshim` afterwards."
docs = """
The wrapper reshims after global installs and uninstalls, so new global
commands get [shims](/dev-tools/shims.html). It is not installed on Windows.
Turn it off to let Corepack or a global `npm install -g npm@...` manage
`bin/npm` directly. See
[Global npm packages](/lang/node.html#global-npm-packages).
"""
env = "MISE_NODE_NPM_SHIM"
type = "Bool"
[node.nvm_dir]
default = "~/.nvm"
description = "Directory of nvm, which `mise sync node --nvm` imports Node.js versions from."
env = "NVM_DIR"
type = "Path"
[node.verify]
default = true
description = "Verify downloaded Node.js archives against the SHA-256 checksums in `SHASUMS256.txt`."
docs = """
When the lockfile has no checksum for an archive, mise downloads
`SHASUMS256.txt`, checks its OpenPGP signature as
[`node.gpg_verify`](#node.gpg_verify) allows, and records the archive's
checksum. Setting this to `false` skips both the checksum file and its
signature check. A checksum already in the lockfile is still verified.
"""
env = "MISE_NODE_VERIFY"
type = "Bool"
[not_found_auto_install]
default = true
description = "Install the tool that provides a command when your shell cannot find that command."
docs = """
When a command is not found in a shell where mise is activated, or a shim
cannot resolve its tool, mise installs the tool that provides the command if a
config file for the current directory requests that tool. It finds the tool
from the registry's list of each tool's commands, so this also covers a
configured tool that has never been installed. A tool configured with a backend
identifier such as `github:owner/repo` or `cargo:name` has no such list, so
mise finds it only once a version of it is installed. Turn this off if the
handler interferes with your shell's own command-not-found behavior.
To also install tools that no config requests, enable
[`not_found_auto_install_registry`](#not_found_auto_install_registry). Has no
effect when [`auto_install`](#auto_install) is `false`. See
[Typing a missing command does not install it](/troubleshooting.html#auto-install-on-command-not-found-does-not-trigger).
"""
env = "MISE_NOT_FOUND_AUTO_INSTALL"
type = "Bool"
[not_found_auto_install_registry]
default = false
description = "Install an unconfigured tool when exactly one registry entry provides a command your shell cannot find."
docs = """
When [`not_found_auto_install`](#not_found_auto_install) finds no configured
tool for the command, mise looks the command up in the registry. If exactly one
enabled tool provides it, mise installs that tool's latest version and adds it
to the global config, as `mise use --global <tool>` does. Ambiguous matches are
skipped, and tools in
[`auto_install_disable_tools`](#auto_install_disable_tools) are never installed
this way.
"""
env = "MISE_NOT_FOUND_AUTO_INSTALL_REGISTRY"
type = "Bool"
[not_found_system_fallback]
default = true
description = "Let a shim run a same-named executable from elsewhere on `PATH` when mise cannot resolve the tool."
docs = """
This can make a configured but uninstalled tool silently run an unrelated
system binary, which is common for commands the OS also ships, such as
`python3`. Set both this and
[`not_found_auto_install`](#not_found_auto_install) to `false` to make such a
shim fail instead.
"""
env = "MISE_NOT_FOUND_SYSTEM_FALLBACK"
type = "Bool"
[npm.bun]
deprecated = "Use npm.package_manager instead."
description = "[deprecated] Install `npm:` tools with bun; same as `npm.package_manager = \"bun\"`."
env = "MISE_NPM_BUN"
hide = true
type = "Bool"
[npm.package_manager]
default = "auto"
description = "Package manager that installs `npm:` tools."
docs = """
Every value except `auto` and `aube` needs that executable on `PATH`. Options
such as `pnpm_args` apply only to the package manager they name. See
[Choosing an installer](/dev-tools/backends/npm.html#choosing-an-installer).
"""
enum = [
{ value = "auto", description = "the embedded aube, or npm when `npm.shell_out` is on" },
{ value = "npm", description = "`npm install -g`" },
{ value = "aube", description = "the embedded aube, even when `npm.shell_out` is on" },
{ value = "aube_cli", description = "a standalone `aube` executable" },
{ value = "bun", description = "bun" },
{ value = "pnpm", description = "pnpm" },
]
env = "MISE_NPM_PACKAGE_MANAGER"
rust_type = "NpmPackageManager"
type = "String"
[npm.shell_out]
default = false
description = "Use the npm CLI instead of mise's built-in client for `npm:` version metadata and default installs."
docs = """
With this on, mise runs `npm view` for version metadata, and the default `auto`
[`npm.package_manager`](#npm.package_manager) installs with `npm install -g`
instead of the embedded aube. An explicit package manager, including `aube`, is
used as chosen. npm must be installed.
Use it for npm behavior the built-in client does not replicate, or to debug a
registry problem with npm itself. See
[Private registries](/dev-tools/backends/npm.html#registry-configuration) for
the npm configuration the built-in client reads.
"""
env = "MISE_NPM_SHELL_OUT"
type = "Bool"
[oci.default_from]
default = "debian:bookworm-slim"
description = "[experimental] Base image for `mise oci` builds when neither `[oci].from` nor `--from` sets one."
docs = """
Choose a base whose libc and shared libraries suit the tools you package. Most
prebuilt tool binaries need glibc, which the default image and `ubuntu:24.04`
provide. An Alpine or other musl base needs musl or static builds; changing the
base does not rebuild installed tools for another libc. `scratch` builds without
a base image. See
[Base images](/dev-tools/mise-oci.html#registry-base-image-support).
"""
env = "MISE_OCI_DEFAULT_FROM"
type = "String"
[oci.default_mount_point]
default = "/mise"
description = "[experimental] Directory inside `mise oci` images that holds tool installs, unless `[oci].mount_point` sets one."
docs = """
It must be an absolute path. The image sets `MISE_DATA_DIR` to it, and tools
install under its `installs` directory, with copied vfox plugins under
`plugins`. The `--mount-point` flag overrides it for one command.
"""
env = "MISE_OCI_DEFAULT_MOUNT_POINT"
type = "String"
[oci.insecure_registries]
description = "Registries, as `host` or `host:port`, that mise contacts over plain HTTP instead of HTTPS."
docs = """
Applies to `mise oci` commands and to `oci::` references in `include` and in
task includes, like Docker's `insecure-registries` daemon option. Loopback
registries such as `localhost:5000` always use plain HTTP and need no entry. An
entry without a port matches the host on any port.
```toml
[settings.oci]
insecure_registries = ["registry.lan:5000", "10.0.0.8:5000"]
```
See [Plain-HTTP registries](/dev-tools/mise-oci.html#plain-http-registries).
"""
env = "MISE_OCI_INSECURE_REGISTRIES"
optional = true
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[offline]
description = "Block every HTTP request, so mise uses only installed tools and cached data."
docs = """
Commands that need the network, such as installing a new tool version, fail.
Use it on air-gapped machines or when the network is unreliable. Offline mode
also turns on [`prefer_offline`](#prefer_offline), the softer mode that shims
and shell activation use by themselves.
"""
env = "MISE_OFFLINE"
type = "Bool"
[os]
default_docs = "host OS"
description = "Operating system of the precompiled binaries mise downloads."
docs = "`darwin` is accepted for `macos`. Other values, such as `linux` or `windows`, are used as written."
env = "MISE_OS"
optional = true
type = "String"
[otel.enabled]
default = false
description = "[experimental] Export OpenTelemetry traces of `mise run`."
docs = """
mise exports traces only when a traces endpoint is also set, with
`OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, and
reads other options, such as `OTEL_EXPORTER_OTLP_HEADERS` and
`OTEL_SERVICE_NAME`, from the standard OpenTelemetry variables. Because export
needs this setting too, an endpoint set for another tool does not make mise send
data. Export also needs `experimental = true`, and offline mode turns it off.
Task output is exported separately, with [`otel.logs`](#otel.logs). See
[OpenTelemetry](/tasks/opentelemetry.html).
"""
env = "MISE_OTEL_ENABLED"
type = "Bool"
[otel.logs]
default = false
description = "[experimental] Export each line of task stdout and stderr as an OpenTelemetry log record."
docs = """
mise exports logs only when a logs endpoint is also set, with
`OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`. Each record
is linked to its task's span, which [`otel.enabled`](#otel.enabled) exports.
Log export also needs `experimental = true`.
This is separate from `otel.enabled` because it sends task output, including
any secret a task prints, to the collector. With log export on, `interleave`
tasks get a pipe instead of the terminal, which can change programs that check
for a TTY, such as their colors, progress bars and prompts. See
[Logs](/tasks/opentelemetry.html#logs).
"""
env = "MISE_OTEL_LOGS"
type = "Bool"
[override_config_filenames]
default = []
description = "Project config filenames that mise looks for instead of `mise.toml`, `.mise.toml` and the other standard names."
docs = """
In each directory, mise loads only files with these names, and
environment-specific files such as `mise.development.toml` still load. The first
name is also the name new config files get. For example, to load `mise.toml` but
not `mise.local.toml` or `.mise.toml`:
```sh
export MISE_OVERRIDE_CONFIG_FILENAMES=mise.toml
```
"""
env = "MISE_OVERRIDE_CONFIG_FILENAMES"
parse_env = "list_by_colon"
rc = true
type = "ListString"
[override_tool_versions_filenames]
default = []
description = "Filenames that mise reads as `.tool-versions` files instead of `.tool-versions`."
docs = """
Set it to `none` to stop reading `.tool-versions` files:
```sh
export MISE_OVERRIDE_TOOL_VERSIONS_FILENAMES=none
```
"""
env = "MISE_OVERRIDE_TOOL_VERSIONS_FILENAMES"
parse_env = "list_by_colon"
rc = true
type = "ListString"
[packslip.exec]
default = false
description = "Let packslip tools run their own executable at install time to generate resources, such as an agent skill."
docs = """
Some releases offer a resource only as a command, for example one that prints a
skill's `SKILL.md`. With this on, mise runs the newly installed executable
during installation to generate it. Resources published as files do not need
this setting.
Shell completions are separate: mise may run a declared completion command when
the shell asks for completions, or for `mise completion --tool`, whatever this
is set to. See
[When mise runs a publisher's command](/dev-tools/packslip-resources.html#resource-selection-and-command-execution).
"""
env = "MISE_PACKSLIP_EXEC"
type = "Bool"
[packslip.stampers]
description = "Hosts that must approve a packslip release before mise lists or installs it, each as `host=PIN`."
docs = """
A stamper is a registry, mirror or review service that publishes a signed list
of the releases it approves. When this is set, a version needs an approval from
at least one of these hosts. `PIN` is the minisign public key the host signs
with, the path of its `.pub` file, or, for a host that signs keylessly from
GitHub, an identity prefix:
```toml
[settings.packslip]
stampers = [
"stamps.example.com=/path/to/stamper.pub",
"reviews.example.com=https://github.com/example/reviews/",
]
```
Replace the example hosts and key path with a service and pin you trust. A
stamp never replaces the vendor's signature, a vendor withdrawal still excludes
the version, and a tool with the `trust = "vendor"` option needs no stamp. See
[Stamps](/dev-tools/packslip-verification.html#stamps).
"""
env = "MISE_PACKSLIP_STAMPERS"
optional = true
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[paranoid]
default = false
description = "Turn on paranoid mode: `true` for every protection, or a list of categories (`config`, `env_files`, `plugins`, `provenance`) for only those."
docs = """
`true` turns on every part of [paranoid mode](/paranoid.html). A list turns on
only the categories it names, and `false` turns them all off:
```toml
[settings]
paranoid = ["env_files"]
```
- `config`: every config file outside global and system config needs your
approval, which is tied to the file's contents, so any edit needs approval
again. `.miserc.toml` files and configs under
[`trusted_config_paths`](#trusted_config_paths) still load without it.
Automatic trust, CI trust and `--yes` for the trust prompt are turned off, and
trust is not shared between worktrees or through a monorepo marker.
- `env_files`: files loaded by `env._.file`, `env._.source` and
[`env_file`](#env_file) need approval tied to their contents.
- `plugins`: mise refuses to install an unregistered community plugin by short
name.
- `provenance`: [`locked_verify_provenance`](#locked_verify_provenance) is turned
on, and a "no attestations" answer from mise-versions is confirmed with GitHub.
From the environment, `MISE_PARANOID=1` selects every category and
`MISE_PARANOID=config,env_files` selects those listed. An unknown category is an
error. See [Paranoid mode](/paranoid.html).
"""
enum = [
{ value = "config", description = "content-bound trust for project config, no automatic or CI trust" },
{ value = "env_files", description = "content-bound trust for env files and sourced scripts" },
{ value = "plugins", description = "refuse unregistered community plugins" },
{ value = "provenance", description = "re-verify provenance on every install" },
]
env = "MISE_PARANOID"
global_only = true
rust_type = "Paranoid"
type = "BoolOrList"
[pin]
description = "Make `mise use` and `mise upgrade --bump` write the resolved version, such as `24.14.0` for `node@24`, instead of the requested one."
docs = """
Same as passing `--pin` every time; `--fuzzy` writes the requested version for
one command. `mise upgrade --bump` also writes resolved versions, replacing
requests such as `latest` or `20` in `mise.toml`. To record exact versions without changing `mise.toml`, use a
[lockfile](/dev-tools/mise-lock.html).
"""
env = "MISE_PIN"
type = "Bool"
[pipx.registry_url]
description = "Older name for `pypi.registry_url`."
env = "MISE_PIPX_REGISTRY_URL"
hide = true
optional = true
type = "String"
[pipx.uvx]
default_docs = "true"
description = "Older name for `pypi.uvx`."
env = "MISE_PIPX_UVX"
hide = true
optional = true
type = "Bool"
[plugin_autoupdate_last_check_duration]
default = "7d"
deprecated = "This setting was never implemented and has no effect. Remove it from your config."
deprecated_remove_at = "2027.10.5"
deprecated_warn_at = "2026.10.5"
description = "[deprecated] Has no effect; it was never implemented."
env = "MISE_PLUGIN_AUTOUPDATE_LAST_CHECK_DURATION"
hide = true
type = "String"
[prefer_offline]
description = "Use cached version lists instead of fetching new ones, and go to the network only when nothing is cached."
docs = """
Unlike [`offline`](#offline), network requests stay possible: when nothing
cached answers a request, mise fetches once, with a short timeout and no
retries. The [versions host](#use_versions_host) is skipped. mise turns this on
by itself for shims and for `mise activate`, `mise hook-env`, `mise env`,
`mise exec`, `mise direnv`, `mise ls`, `mise current`, `mise where` and
`mise which`.
"""
env = "MISE_PREFER_OFFLINE"
type = "Bool"
[prereleases]
description = "Include prereleases in `mise ls-remote`, `latest` and prefix matching for every tool."
docs = """
Same as setting the `prerelease = true` tool option on every tool. Every
backend supports that option except the core `java` plugin, which selects
early-access builds with `release_type = "ea"` instead.
`mise ls-remote --prerelease` does this for one command.
Without it, mise skips prereleases when it resolves `latest` or a prefix such as
`node@24`. A version counts as a prerelease when its source flags it, as GitHub
and Forgejo releases, npm and .NET do, or when it looks like one, such as
`1.0.0-rc1` or `2.0.0-beta.2`. `mise ls-remote` leaves out flagged versions;
backends whose source has no flag, such as cargo, gem, go, http, s3, spm, vfox
and asdf, flag versions that look like prereleases. Other sources, such as
aqua's `github_tag` version source, list every tag there. Draft releases are
always excluded.
"""
env = "MISE_PRERELEASES"
type = "Bool"
[profile]
deprecated = "Use MISE_ENV instead."
description = "Older name for the `env` setting; use `MISE_ENV` instead."
env = "MISE_PROFILE"
hide = true
optional = true
type = "String"
[provenance_api_failures_fatal]
default = true
description = "Fail an install when a provenance API, such as GitHub's attestation API, cannot be reached or queried."
docs = """
Applies to GitHub artifact attestation lookups for aqua and github backend
tools, and to SLSA provenance lookups for github backend tools. Set to `false`
to warn and install without that check, for example on a build network that
cannot reach the GitHub API. Checksum failures, provenance that fails
verification, and provenance that the lockfile already requires for the tool
still fail the install.
"""
env = "MISE_PROVENANCE_API_FAILURES_FATAL"
type = "Bool"
[prune.exclude]
default = []
description = "Tools that `mise prune` never removes, such as `node` or `aqua:BurntSushi/ripgrep`."
docs = """
`mise prune`, `mise ls --prunable` and the automatic removal after
`mise upgrade` keep every version of these tools, even when no tracked config
uses them and even when the tool is named on the command line. Name tools as
elsewhere in mise: `node`, `core:node` and `aqua:BurntSushi/ripgrep` all work,
and a short name matches the same tool as its full name. `mise uninstall` is
unaffected.
Use it for a tool that something outside mise reaches through its install path,
or whose old versions you keep on purpose:
```toml
[settings]
prune.exclude = ["node", "aqua:BurntSushi/ripgrep"]
```
"""
env = "MISE_PRUNE_EXCLUDE"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[pypi.keyring_provider]
description = "Read a `pypi:` index password from a `keyring` command when the index URL names a user but no password."
docs = """
Set to `subprocess` to have mise run `keyring get <index-url> <username>` when
[`pypi.registry_url`](#pypi.registry_url) (or a tool's `registry_url`) contains a
username but no password, such as an Azure Artifacts feed written as
`https://VssSessionToken@pkgs.dev.azure.com/.../simple/{}/`. The printed password
is sent as HTTP Basic credentials when mise lists versions and locks. This is
the same value and lookup uv's `keyring-provider = "subprocess"` uses, so
`mise lock` reaches the index the way `mise install` does through uv. mise also
sets `UV_KEYRING_PROVIDER=subprocess` for the `uv lock` it runs, which ignores
`uv.toml`. The
`keyring` executable must be on `PATH`; if it is missing or has no entry, the
request goes out without credentials. The password is never written to the
lockfile or the version cache. See
[Private indexes](/dev-tools/backends/pypi.html#private-indexes).
"""
enum = ["disabled", "subprocess"]
env = "MISE_PYPI_KEYRING_PROVIDER"
optional = true
type = "String"
[pypi.registry_url]
default_docs = "https://pypi.org/pypi/{}/json"
description = "Package index URL that `pypi:` tools list versions from, with `{}` in place of the package name."
docs = """
Use a JSON API URL such as the default, or a simple index such as
`https://pypi.org/simple/{}/`. A simple index is asked for its PEP 691 JSON
form and falls back to PEP 503 HTML. [`minimum_release_age`](/configuration/settings.html#minimum_release_age)
works when the index supplies PEP 700 `upload-time`; HTML responses have no
timestamps. The URL must start with `http://` or `https://`
and contain `{}`. mise also derives the index's simple URL from it and passes
that to installs, as `UV_INDEX` for uv or `PIP_INDEX_URL` for pipx. A tool's
[`registry_url`](/dev-tools/backends/pypi.html#registry-url) option overrides
it for that tool's version list and dependency locking. `pipx.registry_url` is
an older name for this setting. See
[Private indexes](/dev-tools/backends/pypi.html#private-indexes).
"""
env = "MISE_PYPI_REGISTRY_URL"
optional = true
type = "String"
[pypi.uvx]
default_docs = "true"
description = "Install `pypi:` tools with uv when uv is available, and with pipx otherwise."
docs = """
Set to `false` to install every `pypi:` tool with pipx. The uv-only tool options
`with`, `expose` and `dependency_prereleases`, and dependency-graph locking, are
then unavailable. One tool can opt out with the tool option `uvx = false`, but
`uvx = true` cannot turn uv back on while this is `false`. `pipx.uvx` is an
older name for this setting. See
[Using pipx instead of uv](/dev-tools/backends/pypi.html#using-pipx).
"""
env = "MISE_PYPI_UVX"
optional = true
type = "Bool"
[python.compile]
description = "Compile Python from source with python-build instead of using a precompiled build."
docs = """
`false` uses only precompiled builds: installs fail when none exists, and
`mise ls-remote` lists only precompiled CPython builds and PyPy releases. When
unset, [`all_compile`](/configuration/settings.html#all_compile) decides; if
that is unset too, mise uses a precompiled build when one exists and compiles
otherwise. Has no effect on Windows, which always uses precompiled builds. See
[How mise installs Python](/lang/python.html#precompiled-python-binaries).
"""
env = "MISE_PYTHON_COMPILE"
optional = true
type = "Bool"
[python.default_packages_file]
default_docs = "~/.default-python-packages"
deprecated = "Default python package files are deprecated. Use tool-level postinstall hooks for packages that should be installed into every python version, or use the pypi: backend for CLI tools."
deprecated_remove_at = "2027.11.0"
deprecated_warn_at = "2026.11.0"
description = "[deprecated] Requirements file that mise installs with pip into each new Python version."
docs = """
mise runs `pip install --upgrade -r` with this file. See
[Default packages file](/lang/python.html#default-python-packages).
"""
env = "MISE_PYTHON_DEFAULT_PACKAGES_FILE"
optional = true
type = "Path"
[python.github_attestations]
default_docs = "value of [`github_attestations`](/configuration/settings.html#github_attestations)"
description = "Verify GitHub artifact attestations of precompiled Python builds from python-build-standalone."
env = "MISE_PYTHON_GITHUB_ATTESTATIONS"
optional = true
type = "Bool"
[python.patch_url]
description = "URL of a patch that python-build applies to every Python version it compiles."
docs = """
Precompiled builds are not patched. To patch each version separately, use
[`python.patches_directory`](#python.patches_directory).
"""
env = "MISE_PYTHON_PATCH_URL"
optional = true
type = "Url"
[python.patches_directory]
description = "Directory of per-version patches for the Python versions that python-build compiles."
docs = """
When compiling Python, mise passes `<version>.patch` from this directory to
python-build, for example `3.14.2.patch`. If that file does not exist, mise
warns and builds without a patch.
"""
env = "MISE_PYTHON_PATCHES_DIRECTORY"
optional = true
type = "Path"
[python.precompiled_arch]
default_docs = "host architecture: `x86_64` or `aarch64`"
description = "Architecture of the python-build-standalone build that mise downloads, such as `x86_64_v3` or `aarch64`."
docs = """
On x86-64 Linux, mise picks the build that matches the CPU features mise itself
was compiled for, which for official mise releases is the baseline `x86_64`
build. Set `x86_64_v3` to use the faster build on a CPU with AVX2, or
`x86_64_v2` or `x86_64_v4` for other CPU levels. Give only the architecture;
set the OS with [`python.precompiled_os`](#python.precompiled_os).
"""
env = "MISE_PYTHON_PRECOMPILED_ARCH"
optional = true
type = "String"
[python.precompiled_flavor]
default_docs = "install_only_stripped"
description = "Build flavor of python-build-standalone to download, such as `install_only` or `freethreaded-install_only_stripped`."
docs = """
Flavors are the last part of the asset names in the
[python-build-standalone releases](https://github.com/astral-sh/python-build-standalone/releases).
When unset, mise prefers `install_only_stripped`, then `install_only`, and
never picks a free-threaded build. Only flavors of `.tar.gz` assets match, such
as `install_only` and `freethreaded-install_only_stripped`; the `-full` flavors,
published as `.tar.zst`, do not. See
[Free-threaded Python](/lang/python.html#free-threaded-python).
"""
env = "MISE_PYTHON_PRECOMPILED_FLAVOR"
optional = true
type = "String"
[python.precompiled_os]
default_docs = "host OS: `apple-darwin`, `pc-windows-msvc`, `unknown-linux-gnu` or `unknown-linux-musl`"
description = "OS part of the python-build-standalone build name that mise downloads, such as `unknown-linux-musl`."
docs = """
Set it, with [`python.precompiled_arch`](#python.precompiled_arch) if needed,
to download a build for a platform other than the one mise detects, such as
`unknown-linux-musl` on a glibc host.
"""
env = "MISE_PYTHON_PRECOMPILED_OS"
optional = true
type = "String"
[python.pyenv_repo]
default = "https://github.com/pyenv/pyenv.git"
description = "Git repository that mise clones pyenv from to get python-build."
env = "MISE_PYENV_REPO"
type = "String"
[python.uv_venv_auto]
default = false
description = "Activate, and optionally create, the virtualenv of the uv project around the current directory."
docs = """
mise finds the project by walking up to the nearest `uv.lock`; without one, this
does nothing. The environment is `.venv` next to `uv.lock`, or the path in
`UV_PROJECT_ENVIRONMENT`. See [uv projects](/lang/python.html#uv-projects).
`true` warns since mise 2026.7.0 and is removed in mise 2027.7.0. Use
`"create|source"` or `"source"` instead.
"""
enum = [
{ value = false, description = "off" },
{ value = "source", description = "activate an existing virtualenv" },
{ value = "create|source", description = "create the virtualenv with uv when it is missing, then activate it" },
{ value = true, description = "deprecated; like `create|source`, and also exports `UV_PYTHON` set to the Python version" },
]
env = "MISE_PYTHON_UV_VENV_AUTO"
rust_type = "PythonUvVenvAuto"
type = "BoolOrString"
[python.uv_venv_create_args]
description = "Arguments for `uv venv` when mise creates a virtualenv with uv."
docs = """
Used by [`_.python.venv`](/lang/python.html#python-venv) when it sets no
`uv_create_args`, and by [`python.uv_venv_auto`](#python.uv_venv_auto) when it
creates a virtualenv.
"""
env = "MISE_PYTHON_UV_VENV_CREATE_ARGS"
optional = true
parse_env = "list_by_colon"
rust_type = "Vec<String>"
type = "ListString"
[python.venv_create_args]
description = "Arguments for `python -m venv` when `_.python.venv` creates a virtualenv without uv."
docs = """
A [`_.python.venv`](/lang/python.html#python-venv) directive's own
`python_create_args` takes precedence.
"""
env = "MISE_PYTHON_VENV_CREATE_ARGS"
optional = true
parse_env = "list_by_colon"
rust_type = "Vec<String>"
type = "ListString"
[python.venv_stdlib]
description = "Create `_.python.venv` virtualenvs with `python -m venv` even when uv is installed."
docs = "[`python.uv_venv_auto`](#python.uv_venv_auto) always uses uv."
env = "MISE_VENV_STDLIB"
type = "Bool"
[quiet]
description = "Hide mise's own non-error messages, such as progress and task headers; same as `--quiet`."
docs = """
Sets the log level to `error`. Output from the commands mise runs, such as
tasks, still appears; [`silent`](#silent) hides that too.
[`verbose`](#verbose) takes precedence over this setting.
"""
env = "MISE_QUIET"
type = "Bool"
[raw]
description = "Connect tasks and install commands directly to the terminal's stdin, stdout and stderr."
docs = """
Use it when a task or plugin script needs to prompt for input. mise does not
read the output, so it cannot label or redact it. Only one such command runs at
a time, so tasks run one after another whatever [`jobs`](#jobs) is set to. Same
as `--raw`.
"""
env = "MISE_RAW"
type = "Bool"
[registry_cache_ttl]
default_docs = "1h"
description = "How long a downloaded mise registry stays fresh when `registry_floating` is on."
docs = "Set to `0s` to download it again on every command that may use the network."
env = "MISE_REGISTRY_CACHE_TTL"
optional = true
type = "Duration"
[registry_floating]
default = false
description = "Use the latest released mise registry and the current aqua registry, not only the copies built into mise."
docs = """
The built-in copies remain the fallback when a download fails. Each mise release
is tested with its built-in registries, so this is off by default; turn it on
when your mise package lags behind registry changes, for example on a
distribution that updates mise slowly.
mise downloads the mise registry only for commands that may use the network,
and keeps it for [`registry_cache_ttl`](#registry_cache_ttl). The aqua registry
follows [`aqua.registry_cache_ttl`](/configuration/settings.html#aqua.registry_cache_ttl).
"""
env = "MISE_REGISTRY_FLOATING"
type = "Bool"
[ruby.apply_patches]
description = "Patch files or URLs to apply to the Ruby source before compiling it, one per line."
docs = """
```toml
[settings.ruby]
apply_patches = '''
https://example.com/fix.patch
/opt/patches/ruby-yjit.patch
'''
```
mise applies them through ruby-build, or ruby-install when
[`ruby.ruby_install`](#ruby.ruby_install) is on. Precompiled builds are not
patched.
"""
env = "MISE_RUBY_APPLY_PATCHES"
global_only = true
optional = true
type = "String"
[ruby.compile]
description = "Compile Ruby from source instead of using a precompiled build."
docs = """
`false` uses only precompiled builds: installs fail when none exists, and
`mise ls-remote` and prefixes consider only versions that have one. When unset,
[`all_compile`](/configuration/settings.html#all_compile) decides; if that is
unset too, mise uses a precompiled build when one exists and compiles
otherwise. Has no effect on Windows, where mise installs RubyInstaller2 builds.
See [Precompiled binaries](/lang/ruby.html#precompiled-binaries).
"""
env = "MISE_RUBY_COMPILE"
optional = true
type = "Bool"
[ruby.default_packages_file]
default = "~/.default-gems"
deprecated = "Default ruby gem files are deprecated. Use tool-level postinstall hooks for gems that should be installed into every ruby version, or use the gem: backend for CLI tools."
deprecated_remove_at = "2027.11.0"
deprecated_warn_at = "2026.11.0"
description = "[deprecated] File listing gems to install into each new Ruby version."
docs = """
Each line names a gem, optionally followed by a version constraint or `--pre`.
See [Default gems file](/lang/ruby.html#default-gems).
"""
env = "MISE_RUBY_DEFAULT_PACKAGES_FILE"
type = "String"
[ruby.github_attestations]
default_docs = "value of [`github_attestations`](/configuration/settings.html#github_attestations)"
description = "Verify GitHub artifact attestations of precompiled Ruby builds."
docs = """
Applies when [`ruby.precompiled_url`](#ruby.precompiled_url) names a GitHub
repository, such as the default `jdx/ruby`. Builds from a URL template are not
checked.
"""
env = "MISE_RUBY_GITHUB_ATTESTATIONS"
optional = true
type = "Bool"
[ruby.precompiled_arch]
description = "Architecture name of precompiled Ruby builds, such as `x86_64` or `arm64`, used with `ruby.precompiled_os`."
docs = """
mise uses it only when [`ruby.precompiled_os`](#ruby.precompiled_os) is also
set, and then looks for `<arch>_<os>` builds instead of detecting the platform.
Set both to use builds you host with
[`ruby.precompiled_url`](#ruby.precompiled_url) for a platform jdx/ruby does
not publish, such as musl Linux. See
[Precompiled binaries](/lang/ruby.html#precompiled-binaries).
"""
env = "MISE_RUBY_PRECOMPILED_ARCH"
optional = true
type = "String"
[ruby.precompiled_os]
description = "OS name of precompiled Ruby builds, such as `linux`, used with `ruby.precompiled_arch`."
docs = "See [`ruby.precompiled_arch`](#ruby.precompiled_arch)."
env = "MISE_RUBY_PRECOMPILED_OS"
optional = true
type = "String"
[ruby.precompiled_url]
default = "jdx/ruby"
description = "GitHub repository, as `owner/repo`, or URL template that mise downloads precompiled Ruby builds from."
docs = """
A repository must publish releases with assets named like jdx/ruby's. A URL
template can use `{version}`, `{platform}`, `{arch}` and `{os}`. `{platform}`
is `macos`, `arm64_linux` or `x86_64_linux`, or `<arch>_<os>` from
[`ruby.precompiled_arch`](#ruby.precompiled_arch) and
[`ruby.precompiled_os`](#ruby.precompiled_os). `{arch}` and `{os}` are the
parts of `{platform}` before and after its last `_`, such as `x86_64` and
`linux`; on macOS they are `arm64` and `macos`. When both of those settings are
set, `{arch}` and `{os}` are their values as given.
```toml
[settings.ruby]
precompiled_url = "https://mirror.example.com/ruby/ruby-{version}.{platform}.tar.gz"
```
With a URL template, mise cannot list which versions have builds, and it does
not verify GitHub artifact attestations.
"""
env = "MISE_RUBY_PRECOMPILED_URL"
type = "String"
[ruby.ruby_build_cli_opts]
description = "Options for ruby-build itself, such as `--keep`, passed before the version and install directory."
env = "MISE_RUBY_BUILD_CLI_OPTS"
optional = true
type = "String"
[ruby.ruby_build_opts]
description = "Arguments for Ruby's `configure`, such as `--enable-yjit`, passed through ruby-build."
docs = "mise passes them after ruby-build's `--` separator."
env = "MISE_RUBY_BUILD_OPTS"
optional = true
type = "String"
[ruby.ruby_build_repo]
default = "https://github.com/rbenv/ruby-build.git"
description = "Git repository or ZIP archive URL that mise gets ruby-build from."
env = "MISE_RUBY_BUILD_REPO"
type = "String"
[ruby.ruby_install]
description = "Compile Ruby with ruby-install instead of ruby-build."
env = "MISE_RUBY_INSTALL"
type = "Bool"
[ruby.ruby_install_opts]
description = "Arguments for Ruby's `configure`, passed through ruby-install."
docs = "mise passes them after ruby-install's `--` separator."
env = "MISE_RUBY_INSTALL_OPTS"
optional = true
type = "String"
[ruby.ruby_install_repo]
default = "https://github.com/postmodern/ruby-install.git"
description = "Git repository or ZIP archive URL that mise gets ruby-install from."
env = "MISE_RUBY_INSTALL_REPO"
type = "String"
[ruby.verbose_install]
description = "Show ruby-build's full output while compiling Ruby."
docs = "When unset, it follows [`verbose`](/configuration/settings.html#verbose)."
env = "MISE_RUBY_VERBOSE_INSTALL"
optional = true
type = "Bool"
[rust.cargo_home]
default_docs = "`$CARGO_HOME`, otherwise `~/.cargo`"
description = "Directory used as `CARGO_HOME` for the Rust toolchains that mise manages."
docs = """
Set it with [`rust.rustup_home`](#rust.rustup_home) to keep mise's toolchains
apart from another rustup installation. It takes precedence over a `CARGO_HOME`
in your environment, but a `CARGO_HOME` set in `[env]` takes precedence over
it. See
[Cargo, rustup and installed binaries](/lang/rust.html#where-rustup-and-cargo-live).
"""
env = "MISE_CARGO_HOME"
optional = true
type = "Path"
[rust.default_host]
description = "Host triple that mise passes to `rustup init` as `--default-host`."
env = "MISE_RUST_DEFAULT_HOST"
optional = true
type = "String"
[rust.rustup_home]
default_docs = "`$RUSTUP_HOME`, otherwise `~/.rustup`"
description = "Directory used as `RUSTUP_HOME` for the Rust toolchains that mise manages."
docs = """
Set it with [`rust.cargo_home`](#rust.cargo_home) to keep mise's toolchains
apart from another rustup installation. It takes precedence over a
`RUSTUP_HOME` in your environment, but a `RUSTUP_HOME` set in `[env]` takes
precedence over it. See
[Cargo, rustup and installed binaries](/lang/rust.html#where-rustup-and-cargo-live).
"""
env = "MISE_RUSTUP_HOME"
optional = true
type = "Path"
[safe]
default = false
description = "Load project config without letting it run code or change the environment, for automation that reads untrusted config."
docs = """
Use it for bots and CI jobs that process config you did not write, such as a bot
that runs `mise lock --bump` on pull request branches. Project config then loads
without a trust prompt.
Safe mode refuses template `exec()`, `read_file()` and `get_env()`, tasks, the
`postinstall`, `install_env` and spm `install_command` tool options, asdf
plugin scripts, S3 requests, plugin installs, mise secrets and `mise daemons`,
with an error. It skips hooks, as `--no-hooks` does, and ignores project
`[env]`, `[shell_alias]`, `[settings]`, `[deps]`, lazy tools, `path:` versions,
remote includes, `[bootstrap]` and `[dotfiles]`, so a repository cannot turn off
verification, redirect a backend, run its dependency providers or write files
into your home directory. Project templates see an empty `env`, the hosts a
project `api_url` or download URL names get none of your forge tokens or netrc
credentials, and a project `[tool_alias]` cannot redirect a tool global config
declares.
Global and system config still apply. Version resolution and `mise.lock`
updates keep working for backends that query HTTP APIs, such as core tools,
`aqua:`, `github:`, `pypi:` and `npm:`.
See [Safe mode](/security.html#safe-mode) for the complete lists and what safe
mode does not protect against.
"""
env = "MISE_SAFE"
global_only = true
type = "Bool"
[sandbox.deny_all]
default = false
description = "Deny filesystem access, network access and inherited environment variables by default for `mise run` and `mise exec`."
docs = """
Tasks and the `--allow-*` flags can still add exceptions. Windows does not
enforce filesystem or network rules and filters the environment only partly;
mise warns and runs the command anyway. See
[Sandbox every command](/sandboxing.html#default-restrictions).
"""
env = "MISE_SANDBOX_DENY_ALL"
type = "Bool"
[sandbox.deny_env]
default = false
description = "Deny environment variable inheritance by default for `mise run` and `mise exec`."
docs = """
Tasks and the `--allow-env` flag can still let variables through. On Windows,
the command still inherits mise's own environment. See
[Sandbox every command](/sandboxing.html#default-restrictions).
"""
env = "MISE_SANDBOX_DENY_ENV"
type = "Bool"
[sandbox.deny_net]
default = false
description = "Deny network access by default for `mise run` and `mise exec`."
docs = """
Tasks and flags cannot make exceptions for particular hosts; see
[access to particular hosts](/sandboxing.html#access-to-particular-hosts).
Windows does not enforce it; mise warns and runs the command anyway. See
[Sandbox every command](/sandboxing.html#default-restrictions).
"""
env = "MISE_SANDBOX_DENY_NET"
type = "Bool"
[sandbox.deny_read]
default = false
description = "Deny filesystem reads by default for `mise run` and `mise exec`."
docs = """
Tasks and the `--allow-read` flag can still add exceptions. Windows does not
enforce it; mise warns and runs the command anyway. See
[Sandbox every command](/sandboxing.html#default-restrictions).
"""
env = "MISE_SANDBOX_DENY_READ"
type = "Bool"
[sandbox.deny_write]
default = false
description = "Deny filesystem writes by default for `mise run` and `mise exec`."
docs = """
Tasks and the `--allow-write` flag can still add exceptions. Windows does not
enforce it; mise warns and runs the command anyway. See
[Sandbox every command](/sandboxing.html#default-restrictions).
"""
env = "MISE_SANDBOX_DENY_WRITE"
type = "Bool"
[self_update.api_url]
default = "https://api.github.com"
description = "GitHub API base URL that `mise self-update` gets mise releases from."
docs = """
It must use HTTPS. For GitHub Enterprise, include the API path, such as
`https://github.example.com/api/v3`. Use it with
[`self_update.repository`](#self_update.repository) to serve updates from a
mirror. See [Updating mise](/installing-mise.html#updating).
"""
env = "MISE_SELF_UPDATE_API_URL"
global_only = true
type = "Url"
[self_update.auto]
default = false
description = "Update mise automatically before running eligible commands."
docs = """
With `true`, mise checks for a newer release every
[`self_update.check_duration`](#self_update.check_duration), before commands
that may use the network; a duration such as `"1d"` sets the interval instead.
When one is available, it installs it without updating plugins, then runs the
original command again with the new binary.
Automatic updates are skipped in CI, in offline and prefer-offline modes, in
non-interactive sessions, for shell activation commands, and for installations
whose packager disabled self-update.
```toml
[settings]
self_update.auto = true
```
See [Updating mise](/installing-mise.html#updating).
"""
env = "MISE_SELF_UPDATE_AUTO"
global_only = true
rust_type = "AutoUpdate"
type = "BoolOrString"
[self_update.check_duration]
default = "7d"
description = "How often automatic updates check for a new mise release when `self_update.auto = true`."
env = "MISE_SELF_UPDATE_CHECK_DURATION"
global_only = true
type = "Duration"
[self_update.minimum_release_age]
default_docs = "value of [`minimum_release_age`](/configuration/settings.html#minimum_release_age), else `24h`"
description = "Skip mise releases published more recently than this, for `mise self-update` and automatic updates."
docs = """
Takes precedence over
[`minimum_release_age`](/configuration/settings.html#minimum_release_age) for
`mise self-update`, automatic updates and update notifications, and accepts the
same durations and cutoff dates. `0s` turns the delay off. A version named on
the command line, such as `mise self-update 2026.10.4`, skips the delay;
`--force` does not. `mise self-update --minimum-release-age` overrides this
setting.
```toml
[settings]
minimum_release_age = "7d"
self_update.minimum_release_age = "24h"
```
The install script reads `MISE_SELF_UPDATE_MINIMUM_RELEASE_AGE` instead of this
setting; see [Installer options](/installing-mise.html#installer-options).
"""
env = "MISE_SELF_UPDATE_MINIMUM_RELEASE_AGE"
optional = true
type = "String"
[self_update.repository]
default = "jdx/mise"
description = "GitHub repository, as `owner/repo`, that mise gets its own releases from."
docs = """
Used by `mise self-update`, automatic updates and update notifications. Point
it at a private mirror that holds only the releases your organization approves;
the mirror must keep the official archive names and embedded signatures. mise
authenticates with its usual [GitHub token](/dev-tools/github-tokens.html)
sources. See [Updating mise](/installing-mise.html#updating).
"""
env = "MISE_SELF_UPDATE_REPOSITORY"
global_only = true
type = "String"
[shared_install_dirs]
description = "Extra read-only directories that mise searches for installed tool versions."
docs = """
mise searches these after its own installs directory and never installs into
them on its own; `mise install --shared <DIR>` installs into one. Use them on
shared machines, such as Docker images or bastion hosts, where a base set of
tools is preinstalled and users add their own. The system installs directory,
[`system_installs_dir`](#system_installs_dir), is always searched when it
exists and does not need to be listed. See
[Other shared directories](/dev-tools/system-installs.html#other-shared-directories).
"""
env = "MISE_SHARED_INSTALL_DIRS"
optional = true
parse_env = "list_by_os_path_separator"
rust_type = "Vec<PathBuf>"
type = "ListPath"
[shims.exclude]
default = []
description = "Command names that mise never creates shims for, so they resolve to whatever else is on `PATH`."
docs = """
mise still installs and manages the tool, and the next `mise reshim` removes
existing shims with these names. Version-qualified shims such as `python3.12`
are still created:
```toml
[settings.shims]
exclude = ["python", "python3", "pip", "pip3"]
```
Lazy-tool and plugin-provided shims skip these names too, but a
[command wrapper](/dev-tools/shims.html#command-wrappers) you declare with one
of them still works. Only shims are affected: under `mise activate` without
`--shims`, a tool's whole `bin` directory is on `PATH`, so excluded names are
still found there. See
[Exclude commands from shims](/dev-tools/shims.html#excluding-command-names).
"""
env = "MISE_SHIMS_EXCLUDE"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[shims_dir]
default_docs = "`$MISE_DATA_DIR/shims`"
description = "Directory where mise writes user shims."
docs = """
The path must be absolute after `~` expansion. `mise reshim` can share a
directory such as `~/.local/bin`, replacing or removing only files it
recognizes as mise shims, but `mise activate` treats the whole directory as a
shim directory, so use a dedicated one if you activate mise. Lazy tools
declared in user config put their bootstrap shims here. See
[Rebuild shims with mise reshim](/dev-tools/shims.html#mise-reshim).
"""
env = "MISE_SHIMS_DIR"
global_only = true
optional = true
type = "Path"
[shorthands_file]
deprecated = "Use [plugins] in mise.toml or ~/.config/mise/config.toml instead (same shortname = \"backend-or-url\" rows; see https://mise.jdx.dev/configuration.html#plugins)."
deprecated_remove_at = "2026.12.0"
deprecated_warn_at = "2026.6.0"
description = "[deprecated] File of custom tool shorthands; use `[plugins]` instead."
docs = """
Each line maps a short name to a plugin repository, in the same format as
`[plugins]` in `mise.toml`:
```toml
elixir = "https://github.com/my-org/mise-elixir.git"
node = "https://github.com/my-org/mise-node.git"
```
"""
env = "MISE_SHORTHANDS_FILE"
hide = true
optional = true
type = "Path"
[silent]
description = "Hide all output from `mise run` and `mise watch`, including what tasks print, except errors; same as `--silent`."
env = "MISE_SILENT"
type = "Bool"
[skills.auto_sync]
default = false
description = "Link the active tools' agent skills into the project after `mise install`, `mise use`, and `mise upgrade`."
docs = """
mise runs the equivalent of `mise skills sync` after every install, after
`mise use` changes a version, and after `mise upgrade`, so the links under
[`skills.dir`](#skills.dir) point at the versions active in the project. Only
projects with a mise config get links, and nothing is written outside a project
root. mise touches only links it made, and removes stale ones only when [`skills.prune`](#skills.prune)
is on. See
[Keep project links up to date](/dev-tools/packslip-resources.html#keep-project-links-up-to-date).
"""
env = "MISE_SKILLS_AUTO_SYNC"
type = "Bool"
[skills.dir]
default = ".claude/skills"
description = "Where `mise skills sync` links skills: a path under the project root, or under the home directory with `--global`."
docs = """
Set it to the directory the agents you use read, such as `.agents/skills`. An
absolute path is used as written, and `--dir` overrides it for one run. See
[Choose a skill directory](/dev-tools/packslip-resources.html#choose-a-skill-directory).
"""
env = "MISE_SKILLS_DIR"
type = "String"
[skills.fetch]
default = true
description = "Fetch the agent skills a tool's packslip declares when installing it."
docs = """
mise fetches them at install time, so each installed version carries its own
copy. Turning this off skips fetching from then on; it does not delete skills
already fetched or existing links. See [Skills](/dev-tools/packslip-resources.html#skills).
"""
env = "MISE_SKILLS_FETCH"
type = "Bool"
[skills.prune]
default = false
description = "Remove links mise made for skills that are no longer active, on every `mise skills sync`."
docs = """
Without it, `mise skills sync` keeps those links unless you pass `--prune`. With
it, every sync prunes, including the automatic syncs from
[`skills.auto_sync`](#skills.auto_sync). mise removes only links it made, which
point into its installs directory.
"""
env = "MISE_SKILLS_PRUNE"
type = "Bool"
[slsa]
default = true
description = "Verify SLSA provenance of downloads whose publisher provides it."
docs = """
When `false`, the aqua and github backends skip SLSA checks whatever
[`aqua.slsa`](/configuration/settings.html#aqua.slsa) and
[`github.slsa`](/configuration/settings.html#github.slsa) say.
"""
env = "MISE_SLSA"
type = "Bool"
[sops.age_key]
description = "Private age key for decrypting SOPS files, used before any other key source."
docs = """
Prefer the `MISE_SOPS_AGE_KEY` environment variable to writing a private key
into a config file. See
[Where mise finds the age key](/environments/secrets/sops.html#environment-variables).
"""
env = "MISE_SOPS_AGE_KEY"
optional = true
type = "String"
[sops.age_key_file]
description = "Path of an age key file for decrypting SOPS files, used after `sops.age_key` and before `SOPS_AGE_KEY_FILE`."
docs = """
When neither this nor [`sops.age_key`](#sops.age_key) is set, mise tries
`SOPS_AGE_KEY_FILE`, `SOPS_AGE_KEY` and then `~/.config/mise/age.txt`. See
[Where mise finds the age key](/environments/secrets/sops.html#environment-variables).
"""
env = "MISE_SOPS_AGE_KEY_FILE"
optional = true
type = "Path"
[sops.age_recipients]
deprecated = "This setting has no effect because mise does not encrypt sops files. Remove it from your config. To encrypt a value with age, use `mise set --age-encrypt --age-recipient <recipient> KEY=value`."
deprecated_remove_at = "2027.10.5"
deprecated_warn_at = "2026.10.5"
description = "[deprecated] Has no effect; mise does not encrypt sops files."
env = "MISE_SOPS_AGE_RECIPIENTS"
hide = true
optional = true
type = "String"
[sops.rops]
default = true
description = "Decrypt SOPS files with mise's built-in rops library instead of the `sops` CLI."
docs = """
rops handles age keys. Set to `false` to run `sops decrypt` instead, for AWS
KMS, GCP KMS, Azure Key Vault, HashiCorp Vault or PGP keys. The CLI is slower
and cannot read TOML, so an encrypted `.env.toml` needs rops. See
[Choose a decryption method](/environments/secrets/sops.html#choose-a-decryption-method).
"""
env = "MISE_SOPS_ROPS"
type = "Bool"
[sops.strict]
default = true
description = "Fail when a SOPS file cannot be decrypted, instead of skipping it."
docs = """
Decryption fails when no age key is found, the key cannot decrypt the file, or
the `sops` CLI is missing. Set to `false` to skip the file and continue.
"""
env = "MISE_SOPS_STRICT"
type = "Bool"
[spm.artifactbundle_only]
default = false
description = "Install `spm:` tools only from prebuilt artifact bundles, and fail instead of building from source."
docs = """
A tool with the `artifactbundle = false` option, or a version that selects a Git
revision, then fails to install. See
[`artifactbundle`](/dev-tools/backends/spm.html#artifactbundle).
"""
env = "MISE_SPM_ARTIFACTBUNDLE_ONLY"
type = "Bool"
[status.missing_tools]
default = "if_other_versions_installed"
description = "When to warn that tools requested by config are not installed."
docs = """
mise prints the warning, such as `missing: node@24.14.0`, from the shell hook
of `mise activate` and from commands such as `mise exec` and `mise env`. Tools
marked `lazy = true` are never reported.
"""
enum = [
{ value = "never", description = "never warn" },
{ value = "if_other_versions_installed", description = "warn only when another version of the tool is installed" },
{ value = "always", description = "always warn" },
]
env = "MISE_STATUS_MESSAGE_MISSING_TOOLS"
type = "String"
[status.show_deps_stale]
default = true
description = "Warn in an activated shell when a `[deps]` provider with `auto = true` is out of date."
docs = """
The warning names each stale provider and the reason, such as
`npm (package-lock.json changed)`. See
[Staleness warnings](/dev-tools/deps.html#staleness-warnings).
"""
env = "MISE_STATUS_SHOW_DEPS_STALE"
type = "Bool"
[status.show_env]
description = "When you change directories in an activated shell, list the environment variables that mise adds, changes or removes."
docs = """
Names are shown with `+`, `~` or `-`, without values. Config files that start or
stop applying are listed the same way.
"""
env = "MISE_STATUS_MESSAGE_SHOW_ENV"
type = "Bool"
[status.show_tools]
description = "When you change directories in an activated shell, list the tool versions that become active or inactive."
docs = "Versions are shown as `+node@24.14.0` or `-node@22.21.1`."
env = "MISE_STATUS_MESSAGE_SHOW_TOOLS"
type = "Bool"
[status.truncate]
default = true
description = "Cut the lines from `status.show_env` and `status.show_tools` to the terminal width."
docs = "Setting [`truncate`](/configuration/settings.html#truncate) to `false` turns this off too."
env = "MISE_STATUS_MESSAGE_TRUNCATE"
type = "Bool"
[swift.gpg_verify]
default_docs = "true"
description = "Verify the OpenPGP signature of Swift downloads on Linux."
docs = """
mise checks the signature itself, so `gpg` does not need to be installed. The
global [`gpg_verify`](/configuration/settings.html#gpg_verify) setting sets the
default.
"""
env = "MISE_SWIFT_GPG_VERIFY"
optional = true
type = "Bool"
[swift.platform]
default_docs = "detected from your Linux distribution"
description = "Linux distribution build of Swift to download, such as `ubuntu24.04` or `fedora41`."
docs = """
By default, mise detects your distribution and picks the closest build that the
Swift release publishes. Set this to force one build, or to install without
fetching swift.org's release index. Ignored on macOS and Windows. See
[Linux distributions](/lang/swift.html#linux-distributions).
"""
env = "MISE_SWIFT_PLATFORM"
optional = true
type = "String"
[system_config_file]
description = "One file to use as the system config instead of the config files in `/etc/mise`."
docs = """
When unset, mise reads `conf.d/*.toml`, `config.toml`, `mise.toml` and their
environment and `.local` variants in `/etc/mise` (or `MISE_SYSTEM_CONFIG_DIR`),
and writes such as `mise config set --system` go to `config.toml` there. When
set, mise reads and writes only this file.
"""
env = "MISE_SYSTEM_CONFIG_FILE"
env_only = true
optional = true
type = "Path"
[system_deps]
default = "prompt"
description = "What mise does when a plugin's declared system dependencies are missing before it installs a tool."
docs = """
Dependencies that mise can find, however they were installed, are never
reinstalled. Missing optional dependencies are reported in one line and never
block an install, and the check never fails an install on its own. See
[System dependencies](/tool-plugin-development.html#system-dependencies).
"""
enum = [
{ value = "prompt", description = "list what is missing and offer to install it with the first available package manager; without a terminal and without `--yes`, same as `warn`" },
{ value = "auto", description = "install what is missing without asking, using sudo as `system_packages.sudo` allows" },
{ value = "warn", description = "list what is missing and the commands to install it, then continue" },
{ value = "ignore", description = "skip the check" },
]
env = "MISE_SYSTEM_DEPS"
rust_type = "SystemDepsMode"
type = "String"
[system_installs_dir]
default_docs = "`$MISE_SYSTEM_DATA_DIR/installs` (`/usr/local/share/mise/installs`)"
description = "Directory that `mise install --system` installs into."
docs = """
Lazy tools declared in the system config install here too. The path must be
absolute after `~` expansion. See
[System installs](/dev-tools/system-installs.html#directories).
"""
env = "MISE_SYSTEM_INSTALLS_DIR"
global_only = true
optional = true
type = "Path"
[system_packages.elevate_with]
description = "Command mise uses to get root instead of `sudo`, such as `run0` or `doas`."
docs = """
When unset, mise uses the first of `sudo`, `run0` and `doas` found on `PATH`,
so hosts without sudo, such as secureblue (`run0`) or OpenBSD-style setups
(`doas`), work with no configuration. Set it to pin one:
```toml
[settings]
system_packages.elevate_with = "run0"
```
The command is run as `<command> <program> <args>...`. Without a terminal,
mise checks for passwordless sudo with `sudo -n true`, and runs the command
with `doas -n` or `run0 --no-ask-password` so it fails instead of prompting;
any other command is used only in an interactive terminal. A `doas` rule that
restricts commands must also allow `env`, which mise uses to pass variables
such as `DEBIAN_FRONTEND` to apt. [`system_packages.sudo`](#system_packages.sudo) still turns
elevation off entirely.
Set it to an empty string to never elevate: mise runs package manager commands
as your user, with no `sudo`, `run0` or `doas` in front. Use this where there is
no root to get, such as Termux or a rootless container, and the package manager
works without it. Unset still picks an elevator from `PATH`. See
[Root privileges and sudo](/bootstrap/packages/#sudo).
"""
env = "MISE_SYSTEM_PACKAGES_ELEVATE_WITH"
global_only = true
optional = true
type = "String"
[system_packages.managers]
description = "Package managers that mise may use for `[bootstrap.packages]` and missing plugin dependencies."
docs = """
When unset, mise uses every manager in `[bootstrap.packages]` that is available
on the machine. Names match built-in managers and package manager plugins
alike:
```toml
[settings]
system_packages.managers = ["apt"]
```
Status lists packages of excluded managers as `skipped`, and naming an excluded
manager with `--manager` is an error. For per-OS defaults, set it in a platform
config file such as `mise.linux.toml`, which loads only when that environment
is active, with `-E linux`, `MISE_ENV` or
[`auto_env`](/configuration/settings.html#auto_env). See
[By package manager](/bootstrap/packages/#choosing-which-managers-run).
"""
env = "MISE_SYSTEM_PACKAGES_MANAGERS"
optional = true
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[system_packages.ostree]
default = "error"
description = "What mise does with `dnf:` packages on an image-based Fedora host such as Silverblue or Bazzite."
docs = """
On a host booted from an ostree image, `/usr` is read-only and `dnf install`
fails. Packages are layered with `rpm-ostree install` instead and take effect
on the next boot. Layering is discouraged on these systems, so mise does it only
when you opt in. See
[Fedora Atomic hosts](/bootstrap/packages/dnf.html#fedora-atomic-hosts).
"""
enum = [
{ value = "error", description = "stop and explain why the packages cannot be installed, and what to do instead" },
{ value = "layer", description = "layer missing packages with `rpm-ostree install`; they take effect after a reboot" },
]
env = "MISE_SYSTEM_PACKAGES_OSTREE"
rust_type = "SystemPackagesOstree"
type = "String"
[system_packages.sudo]
default = true
description = "Let mise run `sudo` for steps that need root, such as system packages and `mise install --system`."
docs = """
mise uses sudo only when it is not running as root, and logs each command it
runs with sudo. An interactive session can prompt for your password; a
noninteractive one needs sudo to work without a password.
In `mise bootstrap`, this covers every step that needs root: system packages,
Linux accounts, system files and directories, system services, the firewall,
and Compose projects with `sudo = true`. Some status checks also use sudo to
read root-only state, such as `mise bootstrap firewall status`. For
[`mise install --system`](/dev-tools/system-installs.html#permissions-and-sudo)
and `mise reshim --system`, mise prepares files as your user and uses sudo only
to move the installation, its links and the system shims into protected system
directories. Package manager plugins never use sudo.
Set to `false` to never run sudo. Steps that need root then fail unless mise
already runs as root, and installs into directories you can write still work.
See [Root privileges and sudo](/bootstrap/packages/#sudo).
"""
env = "MISE_SYSTEM_PACKAGES_SUDO"
type = "Bool"
[system_shims_dir]
default_docs = "`$MISE_SYSTEM_DATA_DIR/shims` (`/usr/local/share/mise/shims`)"
description = "Directory where `mise reshim --system` writes shims for system installs."
docs = """
It may be the same directory as [`shims_dir`](#shims_dir); mise then manages one
combined set of shims. The path must be absolute after `~` expansion. See
[Shims for system installs](/dev-tools/system-installs.html#system-shims).
"""
env = "MISE_SYSTEM_SHIMS_DIR"
global_only = true
optional = true
type = "Path"
[task.auto_infer]
default = []
description = "Workspace providers whose package scripts mise imports as tasks, such as `node`."
docs = """
With `["node"]`, the `scripts` of every Node.js workspace package become tasks
named like `node:@acme/web#build`. Requires a monorepo root. An explicit mise task at the same path replaces the imported
one. See [Node.js package scripts](/tasks/workspace-graph.html#node-package-scripts).
"""
env = "MISE_TASK_AUTO_INFER"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[task.cache.audit_report]
description = "[experimental] File that receives every undeclared path found by the `cache.audit` task option."
docs = """
mise writes one JSON object per line, with `task`, `kind` and `path` fields,
while the console shows at most 20 paths per task. Each `mise` invocation that
audits a task replaces the file with that run's findings; tasks restored from
the cache do not run and add nothing. A relative path resolves against the
directory mise runs in. See
[Find undeclared inputs on Linux](/tasks/caching.html#find-undeclared-inputs-on-linux).
"""
env = "MISE_TASK_CACHE_AUDIT_REPORT"
optional = true
type = "Path"
[task.cache.remote_mode]
default = "read-write"
description = "[experimental] How mise uses the remote task cache server."
docs = """
mise uploads results only from GitHub Actions and GitLab CI jobs that push to a
protected branch. Other runs only read, whatever this is set to, and with
`write-only` they do not use the server at all. `mise run --task-cache
local-only` skips the server for one run. See
[Who can write](/tasks/remote-cache.html#who-can-write).
"""
enum = [
{ value = "read-write", description = "read entries when the local cache misses, and upload new results" },
{ value = "read-only", description = "read entries without uploading" },
{ value = "write-only", description = "upload new results without reading entries" },
]
env = "MISE_TASK_CACHE_REMOTE_MODE"
rust_type = "mise_cache_core::RemoteCacheMode"
type = "String"
[task.cache.remote_namespace]
description = "[experimental] Namespace that keeps this project's entries apart on the remote task cache server."
docs = """
Required when [`task.cache.remote_url`](#task.cache.remote_url) is set. The
server also uses it to decide who may read and write. It is an identifier, such
as a repository name, not a secret.
"""
env = "MISE_TASK_CACHE_REMOTE_NAMESPACE"
optional = true
type = "String"
[task.cache.remote_oidc_audience]
description = "[experimental] Audience of the GitHub Actions OIDC token that mise requests for the remote task cache."
docs = """
The workflow needs the `id-token: write` permission. mise refreshes the token
before it expires. [`task.cache.remote_token`](#task.cache.remote_token) and
[`task.cache.remote_token_file`](#task.cache.remote_token_file) take precedence.
See [GitHub Actions OIDC](/tasks/remote-cache.html#github-actions-oidc).
"""
env = "MISE_TASK_CACHE_REMOTE_OIDC_AUDIENCE"
global_only = true
optional = true
type = "String"
[task.cache.remote_token]
description = "[experimental] Bearer token that mise sends to the remote task cache server."
docs = """
Prefer the `MISE_TASK_CACHE_REMOTE_TOKEN` environment variable to writing the
token into a config file. It takes precedence over
[`task.cache.remote_token_file`](#task.cache.remote_token_file) and OIDC. A
request with a credential must use HTTPS, except to a loopback address. See
[Credentials](/tasks/remote-cache.html#credentials).
"""
env = "MISE_TASK_CACHE_REMOTE_TOKEN"
global_only = true
optional = true
type = "String"
[task.cache.remote_token_file]
description = "[experimental] File that mise reads the remote task cache token from before each request."
docs = """
Suits rotating credentials such as Kubernetes projected service account
tokens. See [Credentials](/tasks/remote-cache.html#credentials).
"""
env = "MISE_TASK_CACHE_REMOTE_TOKEN_FILE"
global_only = true
optional = true
type = "Path"
[task.cache.remote_url]
description = "[experimental] Base URL of the remote task cache server."
docs = """
The server must implement the
[remote cache protocol](/tasks/remote-cache-protocol.html); mise appends
`v1/...` to this URL. Remote access also needs
[`task.cache.remote_namespace`](#task.cache.remote_namespace). When unset, mise
uses only the local cache. See [Remote task cache](/tasks/remote-cache.html).
"""
env = "MISE_TASK_CACHE_REMOTE_URL"
optional = true
type = "Url"
[task.cache.stats_report]
deprecated = "This setting has no effect since the built-in action cache was removed. Remove it from your config."
deprecated_remove_at = "2027.10.5"
deprecated_warn_at = "2026.10.5"
description = "[deprecated] Has no effect since the built-in action cache was removed."
env = "MISE_TASK_CACHE_STATS_REPORT"
hide = true
optional = true
type = "Path"
[task.cache_dir]
default_docs = "`$MISE_CACHE_DIR/task-artifacts`"
description = "[experimental] Directory for the task artifact cache."
docs = """
mise keeps entries in a versioned subdirectory, such as `v2`, and includes this
directory in `mise cache clear` and cache pruning. See
[Storage, retention, and output replay](/tasks/caching.html#storage-retention-and-output-replay).
"""
env = "MISE_TASK_CACHE_DIR"
optional = true
type = "Path"
[task.cache_max_age]
description = "[experimental] Remove task artifact cache entries that have not been used for this long."
docs = """
mise enforces it after storing a new entry, and treats an older entry as a
miss. Unset or `0s` keeps entries regardless of age. It is separate from
[`cache_prune_age`](/configuration/settings.html#cache_prune_age).
"""
env = "MISE_TASK_CACHE_MAX_AGE"
optional = true
type = "Duration"
[task.cache_max_size]
description = "[experimental] Maximum total size of the task artifact cache, such as `500MB` or `2GiB`."
docs = """
After storing a new entry, mise removes the least recently used entries until
the cache fits. Unset or `0` means no limit.
"""
env = "MISE_TASK_CACHE_MAX_SIZE"
optional = true
type = "String"
[task.cache_remote_mode]
deprecated = "Use task.cache.remote_mode instead."
deprecated_remove_at = "2027.8.0"
deprecated_warn_at = "2027.2.0"
description = "Deprecated alias for `task.cache.remote_mode`."
enum = ["read-write", "read-only", "write-only"]
hide = true
optional = true
rust_type = "mise_cache_core::RemoteCacheMode"
type = "String"
[task.cache_remote_namespace]
deprecated = "Use task.cache.remote_namespace instead."
deprecated_remove_at = "2027.8.0"
deprecated_warn_at = "2027.2.0"
description = "Deprecated alias for `task.cache.remote_namespace`."
hide = true
optional = true
type = "String"
[task.cache_remote_oidc_audience]
deprecated = "Use task.cache.remote_oidc_audience instead."
deprecated_remove_at = "2027.8.0"
deprecated_warn_at = "2027.2.0"
description = "Deprecated alias for `task.cache.remote_oidc_audience`."
global_only = true
hide = true
optional = true
type = "String"
[task.cache_remote_token]
deprecated = "Use task.cache.remote_token instead."
deprecated_remove_at = "2027.8.0"
deprecated_warn_at = "2027.2.0"
description = "Deprecated alias for `task.cache.remote_token`."
global_only = true
hide = true
optional = true
type = "String"
[task.cache_remote_token_file]
deprecated = "Use task.cache.remote_token_file instead."
deprecated_remove_at = "2027.8.0"
deprecated_warn_at = "2027.2.0"
description = "Deprecated alias for `task.cache.remote_token_file`."
global_only = true
hide = true
optional = true
type = "Path"
[task.cache_remote_url]
deprecated = "Use task.cache.remote_url instead."
deprecated_remove_at = "2027.8.0"
deprecated_warn_at = "2027.2.0"
description = "Deprecated alias for `task.cache.remote_url`."
hide = true
optional = true
type = "Url"
[task.disable_paths]
default = []
description = "Paths that mise does not look for tasks in."
docs = """
Relative paths in a config file resolve from that file's config root, and
relative paths in the environment variable from the directory mise runs in.
See [Exclude paths from discovery](/tasks/task-discovery.html#exclude-paths-from-discovery).
"""
env = "MISE_TASK_DISABLE_PATHS"
parse_env = "list_by_os_path_separator"
rust_type = "BTreeSet<PathBuf>"
type = "ListPath"
[task.disable_spec_from_run_scripts]
default = false
description = "Build task usage specs only from the `usage` field, ignoring deprecated `arg()`, `option()` and `flag()` in run scripts."
docs = """
Defining task arguments with `arg()`, `option()` and `flag()` in run scripts is
deprecated, and mise 2027.5.0 removes it. Enable this to adopt that behavior
now. mise then skips the extra pass that renders run scripts to collect those
calls, which also avoids the empty strings the functions return during that
pass. Define arguments in the task's
[`usage`](/tasks/task-arguments.html#usage-field) field instead; see
[Migrate from Tera argument functions](/tasks/task-arguments.html#tera-templates).
"""
env = "MISE_TASK_DISABLE_SPEC_FROM_RUN_SCRIPTS"
type = "Bool"
[task.monorepo_depth]
default = 5
description = "Maximum directory depth for automatic monorepo discovery, which is deprecated."
docs = """
Only used by automatic monorepo discovery, which mise falls back to when the
root config has no `[monorepo].config_roots`. That fallback is deprecated; list
projects in [`config_roots`](/tasks/monorepo.html#explicit-config-roots)
instead.
`1` finds `projects/`, and `2` finds `projects/frontend/`. If the walk is slow
and every project is at `projects/*`, set it to `2`:
```toml
[settings]
task.monorepo_depth = 2
```
"""
env = "MISE_TASK_MONOREPO_DEPTH"
type = "Integer"
[task.monorepo_exclude_dirs]
default = []
description = "Directory names that automatic monorepo discovery skips."
docs = """
Only used by automatic monorepo discovery, which mise falls back to when the
root config has no `[monorepo].config_roots`. That fallback is deprecated; list
projects in [`config_roots`](/tasks/monorepo.html#explicit-config-roots)
instead.
When empty, mise skips `node_modules`, `target`, `dist` and `build`. A list you
set replaces those defaults, so include any of them you still want skipped,
such as `["node_modules", "vendor"]`.
"""
env = "MISE_TASK_MONOREPO_EXCLUDE_DIRS"
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[task.monorepo_respect_gitignore]
default = true
description = "Skip directories that `.gitignore` files ignore during automatic monorepo discovery."
docs = """
Only used by automatic monorepo discovery, which mise falls back to when the
root config has no `[monorepo].config_roots`. That fallback is deprecated; list
projects in [`config_roots`](/tasks/monorepo.html#explicit-config-roots)
instead.
"""
env = "MISE_TASK_MONOREPO_RESPECT_GITIGNORE"
type = "Bool"
[task.output]
default_docs = "`interleave` when tasks run one at a time, otherwise `prefix`"
description = "Default output style for `mise run`."
docs = """
How much mise prints is a separate choice: [`task.quiet`](#task.quiet),
`--quiet` and `--silent`, or a task's own `quiet` and `silent` properties,
combine with any style. For example, `task.output = "prefix"` with
`task.quiet = true` keeps the task-name labels and hides mise's own messages.
See [Output](/tasks/running-tasks.html#output).
The `quiet` value is deprecated: it warns from mise 2026.9.3 and is removed in
mise 2027.9.3. Use `task.output = "interleave"` with `task.quiet = true`
instead, or `--output interleave --quiet` on the command line.
"""
enum = [
{ value = "prefix", description = "print each line labelled with the task name" },
{ value = "interleave", description = "print output as it arrives, without labels" },
{ value = "keep-order", description = "label lines, stream one task live and buffer the others, then print them in definition order as they finish" },
{ value = "replacing", description = "replace the previous stdout line with each new one, like `mise install` progress; stderr is printed as is" },
{ value = "timed", description = "print only stdout lines that stay on screen for more than a second" },
{ value = "quiet", description = "deprecated; use `interleave` with `task.quiet`" },
{ value = "silent", description = "print nothing from tasks or mise except errors" },
]
env = "MISE_TASK_OUTPUT"
optional = true
rust_type = "TaskOutput"
type = "String"
[task.quiet]
default = false
description = "Hide mise's own messages while tasks run, without changing other mise commands."
docs = """
Hidden messages include the command line mise prints before a task runs, such
as `[build] $ cargo build`. Task stdout and stderr stay visible, and any
[`task.output`](#task.output) style can be combined with this setting.
"""
env = "MISE_TASK_QUIET"
type = "Bool"
[task.remote_no_cache]
description = "Download remote task files and task includes on every run instead of using the cached copy."
docs = """
Applies to tasks whose `file` is a URL, which mise otherwise keeps until
`mise cache clear`, and to `git::` and `oci::` task includes. Same as
`mise run --no-cache`. See [Remote tasks](/tasks/toml-tasks.html#remote-tasks).
"""
env = "MISE_TASK_REMOTE_NO_CACHE"
optional = true
type = "Bool"
[task.run_auto_install]
default = true
description = "Install missing tools automatically before tasks run."
docs = "Has no effect when [`auto_install`](/configuration/settings.html#auto_install) is `false`."
env = "MISE_TASK_RUN_AUTO_INSTALL"
type = "Bool"
[task.show_full_cmd]
description = "Print each task's full command line instead of truncating it to the terminal width."
docs = "Setting [`truncate`](/configuration/settings.html#truncate) to `false` does this for all output."
env = "MISE_TASK_SHOW_FULL_CMD"
type = "Bool"
[task.skip]
default = []
description = "Names of tasks that `mise run` skips."
env = "MISE_TASK_SKIP"
parse_env = "set_by_comma"
rust_type = "BTreeSet<String>"
type = "SetString"
[task.skip_depends]
description = "Run only the tasks named on the command line, skipping their dependencies; same as `mise run --skip-deps`."
env = "MISE_TASK_SKIP_DEPENDS"
type = "Bool"
[task.source_freshness_equal_mtime_is_fresh]
default = false
description = "Treat a task as up to date when its newest source and its outputs have the same modification time."
docs = """
By default, outputs must be strictly newer than every source. Enable this on
filesystems with coarse timestamps, where a build can leave outputs with the
same time as its inputs. See
[Freshness settings](/tasks/caching.html#freshness-settings).
"""
env = "MISE_TASK_SOURCE_FRESHNESS_EQUAL_MTIME_IS_FRESH"
type = "Bool"
[task.source_freshness_hash_contents]
default = false
description = "Decide whether a task's sources changed by hashing their contents instead of comparing modification times."
docs = """
mise compares BLAKE3 hashes of the source contents with those recorded after
the last successful run. This is slower, but checkouts and copies that change
timestamps do not make a task stale. The first run after you enable it always
runs the task. See [Freshness settings](/tasks/caching.html#freshness-settings).
"""
env = "MISE_TASK_SOURCE_FRESHNESS_HASH_CONTENTS"
type = "Bool"
[task.timeout]
description = "Time limit for a whole `mise run` invocation, across every task it runs."
docs = """
A task's own [`timeout`](/tasks/task-configuration.html#timeout) limits each of
its commands; whichever limit is reached first stops the task.
`mise run --timeout` overrides this setting.
"""
env = "MISE_TASK_TIMEOUT"
optional = true
type = "Duration"
[task.timings]
default_docs = "`true` for the `prefix`, `keep-order` and `timed` styles unless output is quiet, otherwise `false`"
description = "Print each task's elapsed time when it finishes."
docs = "`mise run --no-timings` hides the elapsed time for one run."
env = "MISE_TASK_TIMINGS"
optional = true
type = "Bool"
[task_disable_paths]
deprecated = "Use task.disable_paths instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.disable_paths`."
hide = true
optional = true
rust_type = "BTreeSet<PathBuf>"
type = "ListPath"
[task_output]
deprecated = "Use task.output instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.output`."
hide = true
optional = true
rust_type = "TaskOutput"
type = "String"
[task_remote_no_cache]
deprecated = "Use task.remote_no_cache instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.remote_no_cache`."
hide = true
optional = true
type = "Bool"
[task_run_auto_install]
deprecated = "Use task.run_auto_install instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.run_auto_install`."
hide = true
optional = true
type = "Bool"
[task_show_full_cmd]
deprecated = "Use task.show_full_cmd instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.show_full_cmd`."
hide = true
optional = true
type = "Bool"
[task_skip]
deprecated = "Use task.skip instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.skip`."
hide = true
optional = true
rust_type = "BTreeSet<String>"
type = "SetString"
[task_skip_depends]
deprecated = "Use task.skip_depends instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.skip_depends`."
hide = true
optional = true
type = "Bool"
[task_timeout]
deprecated = "Use task.timeout instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.timeout`."
hide = true
optional = true
type = "Duration"
[task_timings]
deprecated = "Use task.timings instead."
deprecated_remove_at = "2027.2.0"
deprecated_warn_at = "2026.8.0"
description = "Deprecated alias for `task.timings`."
hide = true
optional = true
type = "Bool"
[tera_v1]
default = false
deprecated = "tera_v1 is a temporary compatibility escape hatch for templates that still need Tera v1 behavior. Update templates to Tera v2 syntax instead."
deprecated_remove_at = "2027.4.0"
deprecated_warn_at = "2026.10.0"
description = "[deprecated] Render templates with Tera v1 instead of Tera v2."
docs = """
Use it only for templates that need Tera v1 macros or its lenient handling of
undefined variables. In a shared `mise.toml`, set `MISE_TERA_V1 = true` under
`[env]` instead: older mise releases treat it as an ordinary environment
variable, while they reject an unknown setting. It does not apply to
`.miserc.toml`. See
[Migrating from Tera v1](/templates.html#tera-v2-migration).
"""
env = "MISE_TERA_V1"
type = "Bool"
[terminal_progress]
default = true
description = "Show install progress in the terminal window's own progress indicator, with OSC 9;4 escape sequences."
docs = """
mise sends the sequences only to terminals that support them, such as Ghostty,
iTerm2, VS Code's terminal, Windows Terminal and VTE-based terminals such as
GNOME Terminal and Ptyxis, and not to Alacritty, WezTerm or kitty.
"""
env = "MISE_TERMINAL_PROGRESS"
type = "Bool"
[tool_update.check_duration]
default = "24h"
description = "How often mise checks for a newer version of a global tool that sets `auto_update = true`, or of every global tool with `tool_update.global_auto = true`."
docs = """
A tool can set its own interval instead, such as `auto_update = "6h"`.
Intervals under `1h` are raised to `1h`. See
[Automatic tool updates](/dev-tools/#automatic-tool-updates).
"""
env = "MISE_TOOL_UPDATE_CHECK_DURATION"
global_only = true
type = "Duration"
[tool_update.global_auto]
default = false
description = "Update every tool in global config automatically, as if each set `auto_update` to this value."
docs = """
`true` checks every [`tool_update.check_duration`](#tool_update.check_duration),
and a duration such as `"6h"` sets the interval instead. A tool's own
`auto_update` takes precedence, so `auto_update = false` opts one tool out.
Tools in project config are never updated, and exact versions such as
`node = "24.11.1"` stay as they are. See
[Automatic tool updates](/dev-tools/#automatic-tool-updates).
```toml
[settings]
tool_update.global_auto = true
```
"""
env = "MISE_TOOL_UPDATE_GLOBAL_AUTO"
global_only = true
rust_type = "AutoUpdate"
type = "BoolOrString"
[trace]
description = "Set the log level to trace."
env = "MISE_TRACE"
hide = true
type = "Bool"
[truncate]
default = true
description = "Truncate long terminal output to fit the available width."
docs = """
Set to `false` to show complete values in output that fits itself to the
terminal, such as table cells and task command lines. Limits on captured
command output, HTTP response bodies and history data still apply. AI coding
agents always get untruncated output. Commands that truncate also accept
`--truncate` and `--no-truncate` for one run.
"""
env = "MISE_TRUNCATE"
type = "Bool"
[trusted_config_paths]
default = []
description = "Directories whose config files mise trusts without asking."
docs = """
Covers config files at or below these paths, including projects you create
there later. `["/"]` trusts every config file, which turns trust checks off.
They override trust prompts you declined and `mise trust --ignore`, but
[`ignored_config_paths`](#ignored_config_paths) still stops configs from
loading. Paranoid mode still trusts these paths, without tying trust to file
contents. See [Trust by path](/security.html#trust-by-path).
mise first compares each entry as written with the config's canonical path,
which needs no filesystem lookup. Only if none match does it resolve the
entries, once per process. Entries on autofs or network mounts (such as
`/home/...` on macOS, an autofs mount that holds no user homes) cost a lookup
each, so use `~/...` or a path that exists locally instead.
"""
env = "MISE_TRUSTED_CONFIG_PATHS"
global_only = true
parse_env = "list_by_os_path_separator"
rust_type = "BTreeSet<PathBuf>"
type = "ListPath"
[unix_default_file_shell_args]
default = "sh"
description = "Shell that runs a file task on Unix when the task sets no `shell` and the file has no shebang or known extension."
docs = """
Applies when mise runs the file through a shell instead of executing it: when
the file is not executable, or when
[`use_file_shell_for_executable_tasks`](#use_file_shell_for_executable_tasks)
is on. mise appends the file path as the last argument.
"""
env = "MISE_UNIX_DEFAULT_FILE_SHELL_ARGS"
global_only = true
type = "String"
[unix_default_inline_shell_args]
default = "sh -o errexit -c"
description = "Shell and arguments that run inline scripts on Unix, such as a task's `run`, hooks and `postinstall`."
docs = "mise appends the script as the last argument. A task's own `shell` takes precedence."
env = "MISE_UNIX_DEFAULT_INLINE_SHELL_ARGS"
global_only = true
type = "String"
[upgrade.auto_prune]
default = true
description = "Remove the version that `mise upgrade` replaced once `upgrade.prune_after` has passed."
docs = """
The old install stays during that grace period, so running processes can keep
loading files from it. Set this to `false` when something outside mise uses
that path for good, such as a virtualenv built from a mise-managed interpreter;
the old version then stays without a scheduled removal.
Versions still used by another tracked config, a tool stub or a running process
are kept, and may be removed up to a day after that use ends.
`mise upgrade --prune` removes the replaced version at once, and `--no-prune`
keeps it without scheduling removal. See
[`upgrade.prune_after`](#upgrade.prune_after).
"""
env = "MISE_UPGRADE_AUTO_PRUNE"
type = "Bool"
[upgrade.prune_after]
default = "24h"
description = "Grace period before mise removes a version that `mise upgrade` replaced."
docs = """
The replaced version stays at its original path for this long, and a later
mise command removes it. This protects long-running commands that still load
files from the old install. Set to `0s` to remove scheduled versions on the
next mise command. Run `mise upgrade --prune` or `mise prune` to remove them in
the current one.
"""
env = "MISE_UPGRADE_PRUNE_AFTER"
type = "Duration"
[url_replacements]
description = "URL patterns and replacements that mise's HTTP client applies before sending a request, for mirrors and proxies."
docs = '''
A plain key matches anywhere in the URL, and every occurrence is replaced. A key
that starts with `regex:` is a Rust regular expression, and its first match is
replaced. Rules apply in order, and the first one that changes the URL wins.
`MISE_URL_REPLACEMENTS` takes the rules as a JSON object.
```toml
[settings.url_replacements]
"https://github.com/" = "https://github-mirror.example.com/"
```
Rerouting `api.github.com`, or a repository's release and attestation API
paths, also stops mise from using [mise-versions](#use_versions_host) for that
GitHub metadata, so it all comes from the replacement. Rerouting only release
downloads does not. See [URL replacements](/url-replacements.html).
'''
env = "MISE_URL_REPLACEMENTS"
optional = true
parse_env = "parse_url_replacements"
type = "IndexMap<String, String>"
[use_file_shell_for_executable_tasks]
default = false
description = "Run executable file tasks through a shell instead of executing them directly."
docs = """
By default, mise runs a file task that the OS can execute as a program. With
this on, mise starts it with a shell, chosen in this order: the task's `shell`,
the file's shebang, its extension (`.ps1` runs with `pwsh -File`), then
[`unix_default_file_shell_args`](#unix_default_file_shell_args) or
[`windows_default_file_shell_args`](#windows_default_file_shell_args).
"""
env = "MISE_USE_FILE_SHELL_FOR_EXECUTABLE_TASKS"
type = "Bool"
[use_versions_host]
default = true
description = "Get version lists, public GitHub release metadata and attestations from mise-versions before upstream APIs."
docs = """
[mise-versions](https://mise-versions.jdx.dev) is a shared cache that refreshes
version lists for registry tools and public GitHub release data on a schedule.
Using it avoids GitHub's anonymous rate limit in normal installs, including
Docker builds and CI jobs without a GitHub token.
When a command resolves several tools, such as `mise outdated` or `mise
upgrade`, mise reads one index of every tool's newest versions instead of each
tool's version list, and keeps it as long as a version list
([`fetch_remote_versions_cache`](#fetch_remote_versions_cache)). A request the
index cannot answer exactly reads that tool's list as before.
When the host does not list a registry tool's versions, mise lists them from
the tool's own source. GitHub release data, tags, repository contents and
attestations for public repositories come from the host first. When the host
errors (a timeout, a lost connection, or a `429` or `5xx` response), mise asks
`api.github.com` for the same data instead, with your GitHub token if one is
set. If GitHub fails too, release data and tag lists fall back to a copy mise
cached earlier when it has one; otherwise the error names both failures.
Anything the host answers is trusted, including a `404` for a missing release,
tag or repository and an empty list, so those never reach GitHub's anonymous
rate limit.
Paranoid mode also asks GitHub when the host can't settle an attestation
answer. Otherwise mise asks GitHub directly only for a repository the host does
not know, which may be private, and only with GitHub credentials. Private
repositories, GitHub Enterprise, custom GitHub API URLs, and installs with this
setting off need normal [GitHub authentication](/dev-tools/github-tokens.html)
to stay within GitHub's rate limits.
Every backend's list may come from the host, including `npm:`, `pipx:`,
`cargo:`, `gem:` and `go:` tools, when the tool is a registry tool on its
registry backend. The host is skipped for a tool whose source you have
redirected, because its list describes the public one: an npm registry from
`.npmrc` or `NPM_CONFIG_REGISTRY` (or any registry under `npm.shell_out`),
[`pypi.registry_url`](#pypi.registry_url),
[`cargo.registry_name`](#cargo.registry_name), a `GOPROXY`, `GOPRIVATE` or
`GONOPROXY` other than the default, a gem source or a primary `gem sources`
entry other than rubygems.org, [`dotnet.registry_url`](#dotnet.registry_url), an
`AWS_ENDPOINT_URL` for S3, or a local tool option that changes the listing.
`conda:` tools always list from their channel, since which versions exist
depends on the platform.
The host's list can trail a brand-new release, which the default
[`minimum_release_age`](#minimum_release_age) hides anyway. Set this to `false`
to list straight from the source.
When [`url_replacements`](#url_replacements) reroutes `api.github.com`, or a
repository's release or attestation API paths, mise does not use this host for
that GitHub metadata; the replacement is the only source, because this host
describes only github.com. Rules that reroute only release downloads do not
change this, and version lists for registry tools still come from this host.
Every request to the host sends the mise version and invoking shell in the
User-Agent. When mise runs in CI, these requests also send an
`x-mise-ci: true` header and end the User-Agent with ` ci`, for example
`mise/2026.10.10 linux-x64 (2026-10-11) bash ci`.
The host's request logs record each request's IP address, path and query,
User-Agent, and time. They are kept in private storage for up to 35 days and
then deleted automatically. A nightly job turns them into usage counts, such
as monthly active users and installs per tool, keyed by a salted hash of the IP
address.
Set this to `false` to stop these requests. mise still downloads Python's list
of precompiled builds from this host; see
[How mise installs Python](/lang/python.html#precompiled-python-binaries).
`mise ls-remote --no-versions-host` skips the host for one command. See
[A new release is not listed](/troubleshooting.html#new-version-of-a-tool-is-not-available).
"""
env = "MISE_USE_VERSIONS_HOST"
type = "Bool"
[use_versions_host_track]
default = true
description = "Send download statistics to mise-versions after installing a tool."
docs = """
After a successful install of a core or registry tool, mise reports it to
[mise-versions](https://mise-versions.jdx.dev), which shows tool popularity.
Set this to `false` to opt out. Nothing is sent when
[`use_versions_host`](#use_versions_host) is `false`.
The report is a `GET https://mise-versions.jdx.dev/t` request whose query
parameters carry:
- the tool name, its full backend identifier such as `aqua:BurntSushi/ripgrep`
(with any URL credentials, query string, and fragment removed, and left out
when a URL in it cannot be parsed), and the version
- the OS and architecture
The request also sends the mise version and invoking shell, in the User-Agent,
and whether it runs in CI.
The host's request logs store the report with your raw IP address, User-Agent,
and time in private storage for up to 35 days, then delete it automatically. A
nightly job counts installs from these logs, keyed by a salted hash of the IP
address.
"""
env = "MISE_USE_VERSIONS_HOST_TRACK"
type = "Bool"
[verbose]
description = "Show extra output, such as installation logs, and set the log level to debug; same as `--verbose`."
env = "MISE_VERBOSE"
type = "Bool"
[windows_default_file_shell_args]
default = "cmd /c"
description = "Shell that runs a file task on Windows when the task sets no `shell` and the file has no shebang or known extension."
docs = """
Applies when mise runs the file through a shell instead of executing it: when
Windows cannot run the file by itself, or when
[`use_file_shell_for_executable_tasks`](#use_file_shell_for_executable_tasks)
is on. mise appends the file path as the last argument.
"""
env = "MISE_WINDOWS_DEFAULT_FILE_SHELL_ARGS"
global_only = true
type = "String"
[windows_default_inline_shell_args]
default = "cmd /c"
description = "Shell and arguments that run inline scripts on Windows, such as a task's `run`, hooks and `postinstall`."
docs = "mise appends the script as the last argument. A task's own `shell` takes precedence."
env = "MISE_WINDOWS_DEFAULT_INLINE_SHELL_ARGS"
global_only = true
type = "String"
[windows_executable_extensions]
default = ["exe", "bat", "cmd", "com", "ps1", "vbs"]
description = "File extensions, without the dot, that mise treats as executable on Windows."
docs = """
mise tries them in order when it looks up a command name that has no
extension, and a file with one of them counts as a file task. Matching ignores
case.
"""
env = "MISE_WINDOWS_EXECUTABLE_EXTENSIONS"
parse_env = "list_by_comma"
rust_type = "Vec<String>"
type = "ListString"
[windows_powershell_no_profile]
default = true
description = "Pass `-NoProfile` to the PowerShell (`pwsh` or `powershell`) that mise starts, so startup profiles are skipped."
docs = """
This matches `sh -c` and `zsh -c` on Unix, which do not read interactive
startup files. A profile that changes `PATH`, such as one that activates mise
or adds the shims directory, can otherwise shadow a task's own tools and cause
`cannot find binary path` errors.
It applies to tasks, hooks and `watch_files` commands that run through
PowerShell, on any OS, and has no effect on `cmd`, `sh`, `bash` or other
shells. Set it to `false` if your tasks rely on variables, functions or aliases
from your PowerShell profile.
"""
env = "MISE_WINDOWS_POWERSHELL_NO_PROFILE"
type = "Bool"
[windows_shim_mode]
default = "exe"
description = "How mise creates shims on Windows."
docs = """
Use `exe` unless a tool needs one of the others. When `mise-shim.exe` is
missing, mise warns and uses `file`. After mise is upgraded, the next
`mise reshim` rebuilds `exe`, `file` and `hardlink` shims.
"""
enum = [
{ value = "exe", description = "copy `mise-shim.exe` as `<tool>.exe`; works in every shell, with package managers and with `where.exe`, and needs `mise-shim.exe` next to `mise.exe`" },
{ value = "file", description = "write a `.cmd` batch file, plus an extensionless script for Git Bash and Cygwin" },
{ value = "hardlink", description = "create NTFS hard links to `mise.exe`, which must be on the same volume as the shims" },
{ value = "symlink", description = "create symbolic links to `mise.exe`, which needs administrator rights or Developer Mode" },
]
env = "MISE_WINDOWS_SHIM_MODE"
type = "String"
[write_targets.dotfiles]
description = "Global config file where `mise dot add` creates new `[dotfiles]` entries."
docs = """
`mise dot edit` uses it too when it adds an entry. `mise dot track` does not:
it writes new track entries to the global `config.toml`, or to
`conf.d/dotfiles-tracking.toml` when another entry already manages the target.
Existing entries stay in the file that declares them. The path may be absolute,
start with `~/`, or be relative to the `config_root` of the config file that sets it, and may use
templates such as `{{ config_source | dirname }}`. It must name a file that mise loads from the global config
directory, such as `~/.config/mise/conf.d/30-dotfiles.toml`. See
[Send global writes to separate files](/configuration.html#global-section-write-targets).
"""
global_only = true
optional = true
type = "Path"
[write_targets.packages]
description = "Global config file where `--global` package commands create new `[bootstrap.packages]` entries."
docs = """
Used by `mise bootstrap packages use --global` and
`mise bootstrap packages import --global`. Existing entries stay in the file
that declares them. The path may be absolute, start with `~/`, or be relative to
the `config_root` of the config file that sets it, and may use templates such as
`{{ config_source | dirname }}`. It must name a file that mise loads from the global config directory, such as
`~/.config/mise/conf.d/20-packages.toml`. See
[Send global writes to separate files](/configuration.html#global-section-write-targets).
"""
global_only = true
optional = true
type = "Path"
[write_targets.tools]
description = "Global config file where `mise use --global` creates new `[tools]` entries."
docs = """
Existing entries stay in the file that declares them. The path may be absolute,
start with `~/`, or be relative to the `config_root` of the config file that sets it, and may use
templates such as `{{ config_source | dirname }}`. It must name a file that mise loads from the global config
directory, such as `~/.config/mise/conf.d/10-tools.toml`. See
[Send global writes to separate files](/configuration.html#global-section-write-targets).
"""
global_only = true
optional = true
type = "Path"
[yes]
description = "Answer yes to every confirmation prompt, as `--yes` does."
docs = """
Use it in scripts and CI; mise also turns it on when the `CI` environment
variable is set. It also answers the config trust prompt, which records trust,
except in [paranoid mode](/paranoid.html).
"""
env = "MISE_YES"
global_only = true
type = "Bool"
[zig.use_community_mirrors]
default = true
description = "Download Zig from the community mirrors that ziglang.org recommends before trying ziglang.org itself."
docs = """
ziglang.org offers no uptime or speed guarantees and asks automated downloads
to use the [community mirrors](https://ziglang.org/download/community-mirrors/).
Every download is verified against the Zig Software Foundation's signing key,
so a mirror cannot alter it. When every mirror fails, mise downloads from
ziglang.org.
mise refreshes its cached mirror list daily. Without network access to the
list, write one mirror URL per line to `zig/community-mirrors.txt` in the
directory that `mise cache path` prints.
"""
env = "MISE_ZIG_USE_COMMUNITY_MIRRORS"
type = "Bool"