The experimental [daemons] system grows substantially: tasks can declare the daemons they need, [daemon_groups] selects subsets of a project's services, port = "auto" and stable <NAME>_URL hostnames let several git worktrees run the same stack side by side, and CockroachDB, NATS, and SpiceDB join the PostgreSQL and Redis presets. Outside daemons, [bootstrap.packages] gains scoop: and zypper: managers, mise install --system elevates with sudo only for the final publish step, official mise images are published to GHCR and Docker Hub, and a run of brew-cask fixes lets many more casks install unattended.
Highlights
- Daemons as part of the task graph (experimental):
[tasks.x] daemons = [...]starts and waits for services before a task runs, daemons can run a mise task,[daemon_groups]andmise daemons start <group>select subsets, andmise daemons register,urls, andpruneround out the lifecycle. Worktrees get deterministic ports, hostnames, and optionally checkout-localdata_dirstorage without hand-assigned numbers. - More host software from one config: Scoop on Windows and zypper on openSUSE/SLE join the bootstrap managers;
brew-casknow picks the right build for the host macOS release, runs installers that need sudo, applies pkg installer choices andset_ownershipsteps, upgrades pkg-only self-updating casks, and survives DMGs with license prompts or unreadable metadata;brew:resolves formula aliases such asopenssl. - Regressions and integrity fixes:
enterhooks fire again when a shell starts inside a project, npm tools with only pre-releases resolvelatestagain, generatedpre-pushhooks no longer append git's arguments to the task command, andmise installrefuses a lockfile entry whose download URL names a different release than itsversion. Lockfile sidecars now verify on Windows checkouts with CRLF line endings.
Added
-
daemons: Tasks can require daemons and daemons can run tasks.
daemons = ["postgres", "nats"](ortruefor all project daemons) on a task starts them via pitchfork, waits for readiness, and then runs the task; already-running daemons are left alone, and--skip-deps/--dry-runskip them. A daemon can declaretask = "dev:core"withargsinstead ofrun, andinit = [...]runs idempotent setup commands before the long-running process on every start.mise tasks infoshows a task's daemons. (#13340)[daemons] postgres = "18" [daemons.nats] run = "exec nats-server" ready_port = 4222 [tasks.dev] daemons = ["postgres", "nats"] run = "npm run dev"
-
daemons:
[daemon_groups]names project-scoped subsets of daemons; groups may nest other groups and work wherever a daemon name does, including--group.mise daemons startwith no arguments now starts thedefaultgroup when a project declares one, and every project daemon otherwise. (#13347)[daemon_groups] default = ["postgres", "core", "node0"] two-cluster = ["default", "core2"]
-
daemons: A daemon entry with
project = "../other-checkout"and optionalnameruns a daemon defined in another project under that project's tools, environment, and data, and can be used independs.[daemons_settings] namespace = "services"gives daemons stablenamespace/nameIDs (with a per-worktree suffix unlessnamespace_per_worktree = false). Requires pitchfork 2.25.0 or later. (#13339) -
daemons:
port = "auto"(orport = { auto = true, base = 3000, stride = 1 }for custom daemons) keeps the base port in the primary checkout and derives a deterministic offset in each linked git worktree. Resolved ports are exported before startup asPGPORT/DATABASE_URLfor presets and<NAME>_PORTfor custom daemons, andmise daemons ls --jsonreportsportandport_auto. mise does not fall back to another port; startup diagnoses conflicts with running mise-managed daemons in other projects, and two daemons in one project claiming the same port now fail at config load. (#13342) -
daemons: Every daemon with a
portgets a stable hostname served by pitchfork's reverse proxy, exported as<NAME>_URL(for exampleapi.shop.localhostin the primary checkout, orapi.shop-pr-42.shop.localhostin a linked worktree). Per-daemonproxy(a label,true, orfalse) andproxy_tls("terminate"or"passthrough") control routing; thepostgresandredispresets opt out.mise daemons urlslists hostnames, ports, proxy modes, and status. Setproxy = falseon custom daemons that do not speak HTTP. (#13368) -
daemons: CockroachDB (
preset = "cockroachdb"), NATS ("nats"), and SpiceDB ("spicedb") presets install the tool, initialize data, wait for readiness, and exportDATABASE_URL,NATS_URL,SPICEDB_ENDPOINT, andSPICEDB_PRESHARED_KEY. Presets now support named-port overrides such asports.http_port = 8081and typedoptions. Unix-only; NATS and SpiceDB readiness checks needcurl. (#13346) -
daemons:
mise daemons registerinstalls missing tools, validates the daemon graph, and registers pitchfork configuration without starting anything, so a fresh checkout can start on its first hostname request. (#13399) -
daemons:
mise daemons prunefinds daemon state left behind by deleted projects and worktrees, shows paths and sizes, and removes it after confirmation (--dry-runpreviews,--yesconfirms ordinary cases).mise daemons ls --jsonaddsroot,state_dir,data_size, anddata_size_human. (#13338) -
daemons:
data_dir = ".data/postgres"keeps a preset's persistent data inside the checkout (relative to the project root; absolute and~/paths also work), so each worktree gets its own database. Changing the path does not move existing data. (#13408) -
bootstrap: A
scoopmanager for Windows."scoop:extras/vscode" = "latest"adds the bucket if missing, pinned versions install viaapp@version,state = "absent"uninstalls, and--updateopts in toscoop update. Only user-scope installs are managed; entries are skipped on other platforms. (#13324) -
bootstrap: A
zyppermanager for openSUSE and SUSE Linux Enterprise, supporting status, install,name=versionpins (including downgrades), upgrade, and removal, with retries when zypper asks for a package-manager restart. (#13335, @m407) -
bootstrap:
process_typeon[bootstrap.macos.launchd.agents.*]maps to launchd'sProcessType(Background,Standard,Adaptive,Interactive); misspellings are rejected at config time instead of being silently ignored by launchd. (#13402, @waynehoover) -
install:
mise install --systemon Unix downloads, verifies, and unpacks as the invoking user, then uses sudo only to publish into the system install and shim directories. Supports relocatable tools fromaqua,github,gitlab,forgejo,http, ands3without a tool-levelpostinstall;system_packages.sudo = falsedisables elevation. (#13384) -
docker: Official release images at
ghcr.io/jdx/miseandjdxcode/miseforlinux/amd64andlinux/arm64, built from the minisign-verified release binaries. Tags2026.9.12,2026.9, andlatestare a scratch image forCOPY --from=;*-debiananddebianare a Debian slim base withcurlandgit. (#13413)FROM debian:13-slim COPY --from=ghcr.io/jdx/mise:2026.9.12 /usr/local/bin/mise /usr/local/bin/mise
-
config:
unixis accepted as anosselector in[tools],[bootstrap.packages],[doctor.checks], and[dotfiles]variants, matching every non-Windows platform. A concrete OS variant still wins over aunixone. (#13395) -
go: With
goinidiomatic_version_file_enable_tools, thetoolchainline of an activego.workselects the Go version and, as with thegocommand, membergo.modfiles are ignored in workspace mode.GOWORK(auto,off, or an absolute path) is honored. (#13337) -
bazel:
.bazelversionis an idiomatic version file forbazelwhen enabled; only concrete releases are read, solatest,last_green,8.x, and commit hashes select nothing rather than failing. (#13336) -
tasks: File-task
#USAGE include file="..."paths may be relative to the task file or use environment variables such as$MISE_CONFIG_ROOT,$MISE_TASK_DIR, and$MISE_PROJECT_ROOT, so shared flagsets no longer need absolute paths. (#13372) -
dotfiles:
mise dot applynow runs matching[history.reload]commands for the targets it actually wrote, once each after all writes;--dry-runand no-op applies run none. (#13414) -
registry: Added
codegraph(aqua:colbymchenry/codegraph). (#13355, @3w36zj6)
Fixed
- activate: Starting a shell inside a trusted project runs its
enterhook again; a regression in 2026.9.x had limited it tocdinto the project. (#13383) - npm: A tool that publishes only pre-releases (such as
@deepseek-ai/dsh) is no longer reported missing aftermise use npm:...@latest;latestfalls back to the newest installed pre-release when no stable version is installed. (#13390) - npm: On a shared Linux machine, users other than the first to install an
npm:tool no longer fail withfailed to acquire project lock: Permission denied. (#13379) - generate:
mise generate git-pre-commithooks pass only the message file ("$1") forcommit-msg,prepare-commit-msg,applypatch-msg, andsendemail-validate, and no arguments for other hooks, so apre-pushtask no longer runsnpm test origin <url>. Existing hooks change when regenerated. (#13377) - lockfile:
mise installfails before downloading when a locked platform URL provably names a different release than the entry'sversion(for example after a tool bumpedversioninmise.lockwithout refreshing the platform block, or a release dropped a platform).mise lockstill repairs the entry. (#13401) - lockfile: Dependency sidecars under
.mise/locks/verify on Windows checkouts where git rewrote them to CRLF, digests recorded from CRLF bytes by older versions keep working and heal on the next ordinary install, and a relocated sidecar is pinned to the bytes actually written. Repositories can drop.mise/locks/** -textworkarounds. (#13398, #13403, #13407) - brew-cask: Installs the
variationsentry Homebrew publishes for the host macOS release instead of always the newest release's build (Raycast on Sequoia now gets 1.104.x, not the Tahoe-only 2.x), and reportsnot available for this platformfor null variations. (#13376) - brew-cask: Installer scripts that declare
sudo: true(such aslogi-options+) run through mise's sudo path, and$HOMEBREW_PREFIX/$APPDIRplaceholders in installer paths and arguments are expanded. (#13380) - brew-cask: Casks with pkg installer
choices(microsoft-outlook,microsoft-teams) install viainstaller -applyChoiceChangesXML; casks whose flight steps useset_ownership(parsec) install; andmise bootstrap packages upgradehandles self-updating casks that install only from a.pkg(tailscale-app,karabiner-elements) by comparingpkgutilreceipt versions. (#13385, #13386, #13387) - brew-cask: Third-party casks evaluated from Ruby can use
staged_path, unblocking casks such as AeroSpace. (#13369, @soodoh) - install: DMGs with an embedded license agreement no longer stall at
hdiutil'sAgree Y/N?prompt, and DMGs with unreadable root metadata such as.Trashes(for examplemysqlworkbench) extract instead of failing withPermission denied. Applies tobrew-cask,macos-app, and aqua DMG downloads. (#13353, @hisaac; #13378) - brew: Formula aliases and old names (
openssl->openssl@3,act_runner->gitea-runner) resolve forbrew:packages and tap formula dependencies instead of failing with a 404; mise warns to use the canonical name sostatuscan track it. (#13382) - bootstrap: Two spellings of one WinGet or Scoop package (
winget:Git.Gitandwinget:git.git) that disagree onstateorversionare rejected with both names, instead of converging differently per machine. Entries kept apart byosorenvselectors are not compared. (#13334) - github: The GitHub token is sent to
raw.githubusercontent.com, so private Homebrew taps resolve. (#13345, @waynehoover) - github:
{{ version }}inplatforms.<target>.urlis rendered with the resolved version for the GitHub, GitLab, and Forgejo backends, so versioned source archives can followlatest. (#13359, @casparbreloh) - go: Version discovery for modules with hundreds of releases no longer times out with
No versions found;latestresolves directly through the module proxy orgo list, and release dates are fetched only for the newest versions.minimum_release_agestays exact by dating individual undated candidates on demand. (#13362, #13364) - tasks:
mise tasks validaterecognizes child monorepo task references such asdepends = ["//crates/gui:dev"]independs,depends_post,wait_for, and structuredrun. (#13373, @nettlesh) - daemons:
ready_cmdandhealth_cmdprobes run in the owning project's mise environment, so a supervisor shared by several worktrees no longer probes one checkout with another'sAPI_PORT. (#13396) - dotfiles:
mise dot editopens tracked files (mode = "track") in place and inlinecontententries in their declaring config, instead of failing withNo such file or directory; it warns when editing a tracked symlink whose destination history does not capture. (#13332) - history: Checkpoints record the non-default mode of directories containing tracked files, so a
0700~/.claudeholding a trackedsettings.jsonis recreated private on a new machine rather than0755. (#13412) - history: The "histories are unrelated" refusal from
mise dot origin setandmise dot syncnow names the commands for each way out. (#13411)
Documentation
- New "Set up a development stack" guide covering project daemons, worktree isolation, imports, registration, and idle shutdown. (#13389)
- Task templates guide documents Tera v2 components for repeated parameterized snippets inside a
runscript. (#13388) - miser.nvim added to the IDE integration page. (#13406, @carldaws)
- Bootstrap package conflict guidance shortened and corrected. (#13341)
Breaking Changes
- Docker
latesttag:ghcr.io/jdx/mise:latestandjdxcode/mise:latestare now the scratch image (static binary and CA certificates, no shell). CI and dev-container users should switch to thedebiantag and install their tools explicitly; the previous source-built image remains under the unsupporteddevtag. (#13413) - Lockfile version/URL mismatch: Lockfiles whose
versiondisagrees with a platform URL now failmise installinstead of silently installing the wrong release. Runmise lockto regenerate the entry. (#13401) - Generated git hooks: After regenerating with
mise generate git-pre-commit, non-message hooks no longer receive git's arguments. To keep them, edit the hook to use"$@"and declare the arguments withusage. (#13377) - Bootstrap package spellings: Configs declaring one WinGet or Scoop package under two spellings with conflicting
stateorversionare rejected; delete one entry. (#13334) - Daemons (experimental):
mise daemons startwith no arguments starts only thedefaultgroup when one is declared; a project with two daemons resolving to the same port fails to load; custom daemons with aportnow export<NAME>_PORTand<NAME>_URL, so setproxy = falseon non-HTTP daemons. (#13347, #13342, #13368)
New Contributors
Full Changelog: v2026.9.11...v2026.9.12
💚 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.