v2026.4.23

jdx/misev2026.4.23Apr 26, 2026by mise-en-dev

AI Summary

Adds a global `libc` preference for Linux binary variants and per-tool prerelease opt-in for GitHub/Aqua backends, alongside fixes for Node musl downloads and read-only system installs.

Key Highlights

  • Global `MISE_LIBC` setting (musl/glibc/gnu) for selecting Linux binary variants.
  • Per-tool `prerelease = true` opt-in for GitHub and Aqua backends.
  • Fixed Node musl tarball routing to unofficial-builds.nodejs.org to prevent 404s.

New Features

  • Global libc preference
  • Per-tool prerelease opt-in
  • Node musl routing fix

Full Release Notes

A patch release that adds a global `libc` preference and pre-release opt-in for `github:`/`aqua:` backends, alongside fixes for Node musl downloads, read-only system installs, and `mise prune` network hangs.

## Added

- **(backend)** Per-tool `prerelease = true` opt-in for the `github:` and `aqua:` backends ([#9329](https://github.com/jdx/mise/pull/9329)) by @jakedgy. When set, GitHub releases flagged `prerelease: true` show up in `mise ls-remote`, `latest` resolves against the full list including pre-releases, and fuzzy queries like `1.2` can match pre-release tags. Default behavior is unchanged; draft releases are still excluded.

  ```toml
  [tools]
  "github:myorg/mytool" = { version = "latest", prerelease = true }
  "aqua:owner/tool"     = { version = "latest", prerelease = true }
  ```

- **(backend)** Global `libc` setting for selecting Linux precompiled binary variants ([#9404](https://github.com/jdx/mise/pull/9404)) by @jdx. Accepts `musl`, `glibc`, or `gnu` and threads through `Platform::current()`/`PlatformTarget` so generic GitHub asset matching, aqua registry replacements (e.g. `unknown-linux-gnu` ↔ `unknown-linux-musl`), Bun, Python precompiled builds, Node, and vfox `envType` all honor the preference.

  ```sh
  export MISE_LIBC=musl
  ```

## Fixed

- **(install)** Stop rewriting healthy runtime symlinks ([#9410](https://github.com/jdx/mise/pull/9410)) by @jdx. The rebuild path was unconditionally `remove_all` + recreating every `latest -> X.Y.Z` symlink, which became a hard failure under the common Docker pattern where root populates `/usr/local/share/mise/installs/` at build time and a non-root user runs `mise install` at runtime. Healthy symlinks now take a no-op path; the read-only system dir is no longer touched. If a write is genuinely required and can't happen, the install fails loudly instead of silently leaving a stale `latest`.

- **(node)** Route musl tarball URLs to `unofficial-builds.nodejs.org` ([#9409](https://github.com/jdx/mise/pull/9409)) by @jdx. After [#9404](https://github.com/jdx/mise/pull/9404) Node started appending `-musl` to filenames but kept routing through `nodejs.org/dist/` (which doesn't host them), causing 404s and lockfiles where the URL had a `-musl` suffix while the checksum was still pinned to the glibc tarball. The tarball URL and matching `SHASUMS256.txt` now come from the same host, and a custom `node.mirror_url` still passes through unchanged. Lockfile merging is also hardened to drop stale `checksum`/`size`/`url_api` when URLs disagree.

- **(prune)** Skip remote version resolution for tracked configs ([#9406](https://github.com/jdx/mise/pull/9406)) by @jdx. `mise prune` was hitting npm, the Go proxy, and the GitHub API to resolve tracked-config tool versions, which could hang on slow or failing registries. Since prune only protects *installed* versions from deletion, an `offline` flag is now threaded through `ResolveOptions` for prune. `mise upgrade` is unchanged and still queries fresh remote data. Closes [#9405](https://github.com/jdx/mise/discussions/9405).

- **(backend)** Allow unresolved `latest` opt-in ([#9401](https://github.com/jdx/mise/pull/9401)) by @jdx. `latest` now falls back to an unresolved selector only when a backend's unfiltered remote version list is empty *and* the backend opts in via `unresolved_latest_version()`. `pipx` opts in for git-backed requests; backends that require concrete versions continue to fail rather than create literal `latest/` installs. If `minimum_release_age` filters all candidates out, mise still reports no matching version.

- **(schema)** Allow array values in tool `additionalProperties` ([#9400](https://github.com/jdx/mise/pull/9400)) by @JP-Ellis. Configs like `rust = { version = "1.77", components = ["rustfmt", "clippy"] }` are no longer flagged as invalid by linters such as tombi.

## Registry

- Use aqua for `rumdl` ([#9397](https://github.com/jdx/mise/pull/9397)) by @scop
- Add `llmfit` ([#9412](https://github.com/jdx/mise/pull/9412)) by @jylenhof

## New Contributors

- @JP-Ellis made their first contribution in [#9400](https://github.com/jdx/mise/pull/9400)

**Full Changelog**: https://github.com/jdx/mise/compare/v2026.4.22...v2026.4.23