Dotfile groups can now carry block, line and merge edits, merge entries work on INI files, and mode = "fnox" deploys files kept encrypted in fnox. mise secrets also no longer lets a project grant itself keys from your personal fnox config. The rest of the release adds compact-index version listing for gem sources such as GitHub Packages, plus fixes for uninstall, lockfiles, command wrappers, Windows and MSYS2.
Added
-
Edits inside dotfile groups. A
[dotfile_groups.<name>.entries]table can now hold block, line and merge edits alongside whole-file entries. These edits apply only on machines that select the group in[bootstrap] dotfile_groups. Before, edits had to live under[dotfiles], which applies on every machine. Edit entries use the<path>/<id>key form, and a relativesourcestarts at the group root. The edited file must be inside the group's target. Deselecting a group leaves the content its edits already wrote. #15131 (@jdx, @thernstig)[dotfile_groups.common] root = "common" mode = "copy" [dotfile_groups.common.entries] "~/.config/mise/conf.d/private.local.toml/defaults" = { source = "../templates/private.toml", merge = "missing", permissions = "0600" }
-
Dotfile merges into INI files. A
mergeentry can now set keys in INI files such aspip.conf,tox.iniandsetup.cfg. Changed keys are replaced in place, new keys go into their section, and missing sections are added at the end of the file. Comments, other keys, indentation, CRLF line endings and a BOM are all kept. Targets ending in.iniare detected automatically. For any other file name, setformat = "ini". Parsing follows Python'sconfigparser, and a target that doesn't parse is reported and left unchanged. This change also fixes merges in any format whose target is a symlink to its own source: if the source fails to parse, mise now keeps the link instead of replacing it with a copy. #15135 (@jdx, @Mossop)[dotfiles] "~/.config/pip/pip.conf/shared" = { source = "pip/shared.conf", merge = true, format = "ini" }
-
mode = "fnox"for dotfiles containing secrets. This entry writes the file that fnox stores for the target path, so files like~/.npmrcor~/.kube/configstay out of your dotfiles repository. It requires fnox 1.44.0 or newer onPATH. Files are written with mode0600unlesspermissionssays otherwise.mise dot editrunsfnox edit --file.mise dot diffnever prints the content, and dry runs never call fnox.mise dot unapplyremoves the target only while it still matches what fnox stores, unless you pass--force.mise oci buildskips these entries. One limitation:mise dot rollbackjournals the previous plaintext in the local state directory. Only UTF-8 text files are supported. #15134 (@jdx, @owpac)fnox set --file ~/.npmrc
[dotfiles] "~/.npmrc" = { mode = "fnox" }
-
Gem sources without the JSON versions API. If a gem
sourcereturns 404 forapi/v1/versions/<gem>.json, mise now lists versions from the source's compact index (info/<gem>), the same file Bundler uses. As a result,latest, version prefixes,mise outdatedandmise upgradework for gems from GitHub Packages (rubygems.pkg.github.com/<org>) and similar registries. GitHub Packages doesn't publish release dates, sominimum_release_agecan't filter its versions. A 401 from GitHub Packages now comes with a hint about theread:packagestoken scope. #15122 (@waynehoover)
Fixed
mise uninstall ruby 3.4.1no longer removesruby@3.4.12when 3.4.1 isn't installed. A version now matches only when it equals the query or continues it after.,-or+, the same way mise matches versions elsewhere. #15116 (@jdx, @Aqualon)mise lsnow shows lazy tools that haven't been installed as a dimmed(lazy)instead of a red(missing). A baremise upgradeno longer lists them among the tools it resolves.mise ls --jsonstill reports"installed": false, andmise ls --missingstill includes them. #15114 (@jdx)- Installing a
packageManagerentry with a checksum (for examplepnpm@11.7.0+sha512...) no longer forces every later install of that tool onto the npm backend. Installs that an earlier version already pinned recover on their next install. #15124 (@jdx, @foobear) - A command run through a
[wrappers]entry now still goes through other wrappers. For example,noderun from a wrappedpnpmnow gets thenodewrapper'sargsandenv. A wrapper is skipped only for its own nested calls, and that skip is tracked in__MISE_ACTIVE_WRAPPERS. #15126 (@jdx) - Locked installs inside a dotfiles checkout that is linked into your global config, such as
~/.config/mise/conf.d/dotfiles -> ~/dotfiles, no longer fail with "No lockfile URL found". The checkout'smise.lockis now trusted as global config. A projectmise.tomlthat symlinks to your global config still can't vouch for the project's lockfile. #15130 (@jdx, @soodoh) - When
~/.config/miseis a symlink into a dotfiles repository,mise lock --globalwrites npm and Python sidecars tolocks/again instead of.mise/locks/. Existing pointers are rewritten on the next lock. You can delete the old.mise/locks/directory by hand. #15125 (@jdx) - When a backend (
cargo,go,gem,pipx, ...) runs a program that isn't onPATH, the error now names it, for example`cargo` not found. Before, it only said "No such file or directory". #15119 (@jdx, @Mossop) - Under MSYS2, Git Bash and Cygwin,
mise activatefor bash, zsh and fish now exportsMANPATHin POSIX form, somancan use it. Empty entries are kept somanstill uses its default paths. #15117 (@jdx, @PTechoueyres-mic) - On Windows,
mise self-updateretries for about 6 seconds when antivirus briefly locksmise.exe. If replacing the binary fails after the old one has been moved aside, mise copies the new binary into place, so the install directory is never left withoutmise.exe. #15138 (@jdx)
Changed
mise dot statusandmise dot syncno longer start one git process per tracked file. In one test with about 860 tracked files, a warmmise dot statusdropped from about 7s to 1.4s. Output is unchanged. #15127 (@waynehoover)- The README has been rewritten. It now shows a full
mise.tomlexample up front, an updated quickstart, a table of everyday commands, and a section onmise bootstrap. #15136 (@jdx)
Security
- Projects can no longer grant themselves your personal fnox keys. A key defined in fnox's global config, or in a
fnox.tomlin or above$HOME, now counts as yours rather than the project's. If a task'ssecretslist or a{{ secrets.NAME }}reference names such a key, the task fails before any secret is resolved. The error names the file that defines the key.--secrets-allleaves these keys out, whilemise run --secrets NAMEandmise x --secrets NAMEstill pass them because you named them yourself.mise secrets lsandmise tasks validatereport these grants as problems of kindpersonal. To give a key to the project, define it in the project'sfnox.toml. This needs a fnox release that reports where each key is defined. With older fnox, behavior is unchanged. mise secrets is still experimental. #15133 (@jdx)
Full Changelog: v2026.10.22...v2026.10.23
💚 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.