github jdx/mise v2026.10.21
v2026.10.21: Easier dotfiles setup from a checkout or Stow packages, plus `prune --force` for casks

2 hours ago

You can now keep mise's global config inside your dotfiles checkout, and deploy Stow-style packages without writing a table for each one. Dotfiles also get new protections for template entries, and mise bootstrap packages prune can force-remove casks it cannot prove are unchanged. The rest of the release fixes bugs in monorepos, lockfiles and pypi locking.

Added

  • Bootstrap from a dotfiles checkout with --config-dir. mise bootstrap --from accepts --config-dir <path>. It links mise's config directory (~/.config/mise, or wherever XDG_CONFIG_HOME/MISE_CONFIG_DIR point) to that path inside the checkout, then bootstraps from it. config.toml, config.<env>.toml, conf.d/ and miserc.toml in the repository all act as global config from the first run. After that, git -C ~/.dotfiles pull && mise bootstrap is enough, and mise use -g and mise dot add write into the checkout.

    mise bootstrap --from <dotfiles-git-url> --from-dir ~/.dotfiles --config-dir .config/mise

    The path must stay inside the checkout. The existing config directory must be missing, empty, or already that link; mise refuses anything else and leaves it alone. --dry-run creates no link. The docs now recommend mise dot track ~/.config/mise, which tracks the whole config directory rather than only config.toml. Files ending in .local.toml stay on each machine. #15025 (@jdx, @lhs-12, @Mossop)

  • Stow packages need no [dotfile_groups] tables. If a name in [bootstrap] dotfile_groups has no matching table but is a directory under dotfiles.root, mise treats it as a group with the default settings: that directory is deployed into ~ file by file. A table with the same name still overrides the defaults. mise dot add --group, mise dot unapply --group and orphan reporting work for these groups too. #15025 (@jdx, @lhs-12, @Mossop)

    [bootstrap]
    dotfile_groups = ["kitty", "nvim", "zsh"]
  • mise bootstrap packages prune --manager brew-cask --force. This removes mise-installed casks that prune skips because it cannot prove they are unchanged, such as self-updating apps, casks with install steps, and casks installed before mise recorded prune metadata. Without --force, prune now lists which casks --force would remove. A forced prune removes only what the receipt recorded and only while it is still where mise put it. It still skips casks Homebrew owns, casks without a mise receipt, interrupted installs and shared targets. Use --dry-run to preview. #14985 (@jacobbednarz)

  • mise dot apply warns before overwriting an edited template target. If you edited a rendered template target by hand since mise last wrote it, apply now warns that the edit will be overwritten and names the source to move it into. apply still overwrites the file, so unattended runs are not blocked. #15020 (@jdx, @owpac)

  • Registry: tuios (aqua:Gaurav-Gosain/tuios). #14990 (@Gaurav-Gosain)

Fixed

  • Dotfiles
    • mise dot add on a mode = "template" entry now refuses by default. Before, it copied the rendered file over the template source, which deleted the template code and could write secrets pulled in with exec() into your repository in clear text. If you really want to capture the rendered file, pass --force. #15019 (@jdx, @owpac)
    • Switching from Stow no longer destroys source files. When Stow had linked a whole directory into the source, symlink-each apply failed, and the suggested --force replaced each source file with a link to itself. Apply now replaces the folded link with a real directory of links, without needing --force. #15025 (@jdx, @lhs-12, @Mossop)
    • mise bootstrap --adopt --dry-run now previews the whole config directory, including conf.d/, config.<env>.toml and this machine's miserc.local.toml. Before, it only previewed config.toml. #15025 (@jdx, @lhs-12, @Mossop)
  • Config and monorepos
    • With monorepo.config_roots = [".", "child"], a child with no tool overrides lost the tools it inherits from the root config and fell back to global versions. This broke mise install --monorepo --locked. Each declared root now loads its full config hierarchy. #15023 (@jdx, @swizzlr)
    • Running mise run //app:task from the monorepo root with MISE_LOCKED=1 now looks up idiomatic version files such as app/.node-version in app/mise.lock, not the root lockfile. #15021 (@jdx)
    • When .nvmrc is a symlink to .node-version, the .node-version file is read again. mise still skips .nvmrc with a warning, but that skip no longer hides .node-version. Before, the directory resolved no Node version (regression in 2026.10.19). #15006 (@jdx, @jjb)
  • Lockfiles
    • mise lock now re-resolves platform entries whose URL points to a different release than the locked version. This happens, for example, after Renovate bumps the version in mise.lock. Before, mise lock left the old URL and checksum, and mise install --locked then refused the lockfile. #15010 (@jdx)
    • A mise lock sweep with no tool arguments no longer aborts when a pypi:/pipx: tool sets uvx_args or pipx_args. That tool gets a warning and a version-only lock entry. Naming the tool explicitly still errors. #15030 (@jdx)
    • For pypi: tools, mise lock now checks that the resolved uv dependency graph can actually be installed with uv sync --frozen --no-build. If it can't, for example because a dependency has no wheel for the interpreter, mise warns and keeps a version-only entry. Before, mise wrote a graph that the next mise install failed on. #15031 (@jdx)
  • Other
    • mise doctor no longer lists uninstalled lazy = true tools as problems. The toolset list marks them (lazy), and --json adds "lazy": true. #15024 (@jdx)
    • packslip: installs on shared CI runners no longer fail when raw.githubusercontent.com returns a 429. mise now asks mise-versions whether a repository publishes a release list, and falls back to GitHub when the mirror is unavailable, use_versions_host is off, or a url_replacements rule applies. #15032 (@jdx)
    • SmolVM (smol-machines/smolvm) installs through aqua again. mise now rewrites the absolute symlinks in its guest root filesystem as relative links inside the install directory. Links that escape the install directory are still rejected. #15015 (@jdx)

New Contributors

Full Changelog: v2026.10.20...v2026.10.21

💚 Sponsor mise

mise is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.

If mise saves you or your team time, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep mise fast, free, and independent.

Don't miss a new mise release

NewReleases is sending notifications on new releases.