This release centers on running mise safely against untrusted config, shipping node-free npm: version resolution and installs, and replacing external tools (skopeo/crane, gpg) with built-in, dependency-free implementations. Along the way it fixes a prefer_offline timeout regression, several config/env correctness issues, and platform-specific problems on Windows and macOS.
Highlights
- New
MISE_SAFE=1mode turns mise into an inert config reader so automation (CI, Renovate) can runmise lock --bumpagainst untrusted branches without trust prompts or arbitrary code execution. - The
npm:backend no longer needs node or npm installed to resolve or install packages — version metadata is fetched over HTTP and installs run in-process via the embedded aube package manager. mise oci pushgained a full built-in registry client: no more skopeo/crane, with blob dedup, chunked uploads, retries, cross-repo mounts, layer reuse from prior images, and multi-arch image indexes.
Added
-
Safe mode: a new global-only
safesetting (MISE_SAFE=1) makes mise refuse or ignore anything that would let project config execute code or inject environment. Blocked (with errors): templateexec()/read_file(),_.source, hooks, tasks, asdf plugin scripts, and plugin installs. Ignored: project[env],_.path,_.file,[shell_alias], and[settings]. HTTP-based version resolution, lockfile refresh/bump, and already-installed/embedded plugins keep working. Because a config loaded this way is inert, safe mode also skips the trust requirement. (#11146, #11151 by @jdx)MISE_SAFE=1 mise lock --bump --dry-run --json # detect updates with zero code execution, no trust needed -
mise lock --bump: advance fuzzy lockfile selectors (latest,lts, prefixes like"20") to the newest matching remote versions without installing anything and without touchingmise.toml. Exact pins stay put. Pairs with--jsonand--dry-runfor a CI job that opens lockfile-only PRs. (#11145 by @jdx)$ mise lock --bump --dry-run --json [{ "name": "node", "backend": "core:node", "old_versions": ["22.14.0"], "new_versions": ["22.15.0"] }]
-
Node-free
npm:backend:mise ls-remote npm:*andlatestresolution now query the npm registry directly over HTTP, and installs run in-process through the embedded aube package manager. node is only needed to run installed tools (and their lifecycle scripts), not to install them. User~/.npmrc, scoped registries, auth, andminimum_release_ageare honored. A newnpm.shell_outsetting (MISE_NPM_SHELL_OUT) routes both metadata and installs through the npm CLI for setups relying on npm-only config likecafileor client certs. (#11147, #11149 by @jdx) -
Built-in OCI registry client:
mise oci pushno longer requires skopeo or crane. It uses an in-tree OCI Distribution client that uploads only blobs the registry is missing, resolves credentials the way docker/podman do (docker login/podman loginis all the setup needed), and answers registry auth challenges so private base-image pulls via--fromalso work.mise oci run --engine dockernow streams the image intodocker loadinstead of needing skopeo. The--toolflag was removed. (#11132 by @jdx) -
OCI push robustness: large layers upload in 64 MiB chunks, transient failures retry with mise's standard backoff, base layers are mounted cross-repo (
?mount=) when they already live on the destination registry (zero bytes transferred), and pushes/pulls now show byte progress. A newoci.insecure_registriessetting opts non-loopback registries into plain HTTP. (#11141 by @jdx) -
OCI layer reuse:
mise oci pushreuses unchanged tool layers from the previously pushed image (or--cache-from REF), skipping the tar/gzip build entirely — reused tools don't even need to be installed locally.--no-cacheforces a full rebuild. (#11142 by @jdx) -
Multi-arch OCI images:
mise oci push --update-indexpoints a tag at an OCI image index and upserts the current platform while preserving entries pushed by other architectures, so one runner per arch can assemble a multi-arch tag. (#11144 by @jdx) -
Built-in signature verification: Node.js and Swift download signatures are now verified in-process with the pure-Rust rPGP crate against the bundled keyrings, dropping the external
gpgbinary dependency. Note: previously, ifgpgwas missing and the setting was unset, verification was silently skipped; now verification always runs when enabled — opt out withgpg_verify = false. (#11148 by @jdx) -
Relative bootstrap repo paths:
[bootstrap.repos]destination keys can now be relative paths, resolved against the declaring project's root (with guards preventing escape outside the project tree), making a project'smise.tomlportable across machines. (#11155 by @lilienblum)
Fixed
- http:
mise lock,ls-remote,outdated, andupgradeno longer get capped to a single 3s no-retry attempt whenprefer_offlineis set — they honor the configuredfetch_remote_versions_timeoutand retry budget again, fixing spurious timeouts. Interactive fast paths keep their bounded behavior. (#11190 by @jdx) - lock: unfiltered
mise lockno longer prunes OS-restricted tool entries (e.g.os = ["macos"]) when run on a platform that doesn't target them, keeping shared lockfiles stable across platforms. (#11175 by @jdx) - env: values loaded from
_.fileenv files now resolve references to variables defined in earlier files or[env]blocks instead of collapsing to empty, fixing flaky dotenv behavior. (#11158 by @Marukome0743) - env:
[env] _.sourcenow works on Windows by resolving a real POSIX bash (Git Bash / MSYS2, honoringMISE_BASH_PATH) instead of the WSL launcher or a missingbash.exe, and correctly filters MSYS runtime noise and converts prepended PATH entries back to Windows form. (#11097 by @JamBalaya56562) - config:
trusted_config_paths(MISE_TRUSTED_CONFIG_PATHS) now overrides configs previously added to the ignore list, so a settings-trusted config is actually discovered and loaded. (#11152 by @JamBalaya56562) - config:
env/varsarray parsing is now consistent — accidental array forms forvarsand taskenv/varsare rejected with clear errors, while the intentional[[env]]and directive-level arrays (_.source,_.file,_.path) remain supported. (#11060 by @risu729) - config:
mise config setno longer panics when descending into a non-table value. (#11153 by @Marukome0743) - config: clearer warnings for unsupported semver ranges. (#11176 by @risu729)
- hook-env: entering a directory with an untrusted config now prints a single concise warning (
... is not trusted, run 'mise trust' to enable it) instead of the full error chain. Explicit commands still show the full trust error and prompt. (#11159 by @lilienblum) - activate:
mise activate zshno longer hangs non-interactive login shells under Rosetta — a v2026.7.11 regression where env-state snapshotting autoloaded thezsh/parametermodule viadlopen. (#11188 by @jdx) - brew-cask: case-insensitive app bundle lookup (fixing casks like
yaak) and correct resolution of preflight-generated wrapper scripts on the extract stage (fixingvlc). (#11164 by @donbeave) - brew: cask binaries can symlink into
/usr/localon arm64. (#11174 by @jdx) - backend: qualified prerelease suffixes are now detected correctly. (#11179 by @risu729)
- completions: avoid a network lookup during usage completion. (#11169 by @jdx)
- link: clear a stale incomplete marker when linking a tool. (#11150 by @Marukome0743)
- shim: unresolved Windows exe-shim dispatch (e.g. a project-scoped tool run outside the project) now shows the actionable "no version is set" guidance instead of an opaque "cannot find binary path". (#11189 by @jdx)
- vfox: preserve inner quotes when a vfox Lua command dispatches through
cmd.exeon Windows, fixing commands such as the Yarn 2+ install flow. (#11166 by @finalchild) - github/gitlab/forgejo: statically-linked
linux-muslassets are now considered a fallback for Android/Termux when a package publishes no Android-specific asset, so tools like starship, bat, and hk can install there. (#10730 by @bltavares) - deps: avoid installing tools during dry runs, and enforce the experimental gate for task providers. (#11016, #11177 by @risu729)
Documentation
- Document environment-variable backing for file-task arguments and flags, including CLI/env/default precedence. (#11165 by @zeitlinger)
Breaking Changes
mise oci push --toolhas been removed. Usemise oci build -o ./imgfollowed byskopeo copyif you need the old escape hatch. (#11132)- Node/Swift signature verification now always runs when enabled (external
gpgis no longer required). If you relied on a missinggpgbinary to skip verification, setgpg_verify = falseexplicitly. (#11148) - The unreleased
npm.use_npm_viewsetting is replaced bynpm.shell_out(MISE_NPM_SHELL_OUT). (#11149)
New Contributors
- @donbeave made their first contribution in #11164
- @lilienblum made their first contribution in #11159
Full Changelog: v2026.7.11...v2026.7.12
💚 Sponsor mise
mise is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools. Development is funded by sponsors.
If mise saves you or your team time, please consider sponsoring at jdx.dev. Individual and company sponsorships keep mise fast, free, and independent.