mise-en-place
The front-end to your dev env Pronounced "MEEZ ahn plahs"
- site: https://mise.jdx.dev/
A new macos-app bootstrap manager installs .app bundles from a pinned URL and checksum when no Homebrew cask exists, task templates now compose usage flags and can be extended from file tasks, and Swift on Linux picks its distro build from swift.org's release index instead of a hard-coded map that 404'd on arm64 and on newer Fedora, Amazon Linux, and Arch hosts. Install failures also become far more actionable: errors name the minimum_release_age cutoff that hid every version, the child's last stderr line, or the shared libraries a Swift toolchain cannot load.
Highlights
- Apps without a cask:
"macos-app:<name>"entries in[bootstrap.packages]download, checksum-verify, and install a.appinto/Applicationsusing mise's existing cask pipeline, with stricter ownership rules for apps already at the target. - Task templates that actually share things: a task that
extendsa template now inherits the template'susageflags alongside its own, file tasks can write#MISE extends="...", and a template'svarscan read the values the extending task supplies. - Swift on Linux: arm64 downloads resolve on every distro, the build is chosen from what a release actually publishes (with a warning when a fallback is used), and a fallback that cannot start names the missing libraries instead of exiting 127 after a 1 GB download.
Added
-
bootstrap: The
macos-apppackage manager installs a macOS.appbundle from a vendor or internal download.version,url,sha256, andartifactare all required ("latest"is rejected because mise cannot discover releases behind a plain URL);{{version}}is interpolated intourl, so a release bump is a two-field edit. Only.dmgand.ziparchives containing an app bundle are supported, state is kept in mise's state directory rather than Homebrew's Caskroom, and an app already at the destination that this entry does not own is refused unlessadopt = trueand the contents match.mise bootstrap packages upgradecannot discover new versions for these entries, andprune --manager macos-appis unsupported. Preferbrew-caskwherever a cask exists. (#13279)[bootstrap.packages."macos-app:example"] version = "1.2.3" url = "<HTTPS URL of the .dmg or .zip; {{version}} is interpolated>" sha256 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" artifact = "Example.app" -
tasks: A task that names a template with
extendsand declares its ownusagenow gets the template's flags too, listed first in--help. Previously the task's spec replaced the template's entirely, so shared flags had to be copied into every task. Workspace-root task defaults still only fill inusagewhen the task has none. A flag declared in both places is listed twice; declare each flag in one place, or use usage flagsets for replacements. (#13310)[task_templates.deploy] usage = 'flag "--env <env>" help="Target environment"' [tasks.deploy-api] extends = "deploy" usage = 'flag "--replicas <n>" help="How many to run"' run = 'echo "env=$usage_env replicas=$usage_replicas"' -
tasks: File tasks (including remote HTTP and
git::scripts) can use#MISE extends="<template>"in their header to inherit tools, env, description, aliases, and other fields from a task template; previously the field was warned about and ignored. A task whose command is a script file no longer picks up a template'srun. (#13307) -
swift: When a Linux install fails its
swift --versioncheck, mise runslddover the toolchain and lists every unresolved shared library (for examplelibform.so.6, libncurses.so.6, libpanel.so.6on an Arch-family host running a ubi9 build), with the tool'sinstall_envapplied so anLD_LIBRARY_PATHremedy is not misreported.docs/lang/swift.mddocuments the workaround. (#13319)
Fixed
- swift: Installing Swift on arm64 failed with a 404 on every Linux distro except Ubuntu (and on Windows arm64 lock entries) because only Ubuntu used swift.org's
<platform>-<arch>download directory. (#13293, fixes #13291) - swift: The Linux distro build is now chosen from swift.org's release index rather than a hard-coded map: the host's exact distro version wins, then the newest published build older than the host, then the family's oldest, with
ID_LIKEconsulted (Linux Mint gets an Ubuntu build) and unknown distros such as Arch falling back toubi9. Every compromise is announced with a warning, musl hosts and unsupported architectures fail before downloading, andswift.platformstill overrides selection without contacting swift.org. Theswift_platformlockfile option now records the host as detected (e.g.fedora40instead offedora39); mismatched entries are re-resolved on the next lock. (#13297, fixes #13289) - config:
install_envvalues are now rendered as templates like other tool options, soLD_LIBRARY_PATH = "{{env.HOME}}/.local/lib/compat"reaches the install subprocess expanded rather than literally.{{version}}is left unchanged. (#13314) - install: When
minimum_release_age(default24h) hides every candidate, the error names the setting and cutoff, how many releases it hid, the newest one with its release and eligibility dates, and a copy-pasteable exact pin to install it now, instead ofno versions found ... matching date filter. A query that matched nothing is no longer blamed on the filter. (#13308) - cmd: A failing command run by mise (installs, tasks, plugin scripts) now appends the child's last non-empty stderr line to the error, e.g.
exit code 127; last stderr: swift: error while loading shared libraries: libncurses.so.6 .... This also reaches the final error block under--quiet, where stderr was previously never shown. (#13315) - tasks: A broken
usagespec now reports the task name and the parser's diagnostic (invalid usage spec for task 'deploy'followed by the reason) instead of a bareInvalid usage config; file tasks render the same diagnostic rather than a Debug dump, and a missing or unreadable script is reported as such rather than as a bad spec. (#13312) - tasks: A task template's
varscan now read the vars the extending task supplies, so{{ vars.opt | default(value='none') }}in a template sees the task'soptinstead of always taking the default. Literal vars within a single task are also bound first, sovars = { msg = "hi {{ vars.who }}", who = "world" }works regardless of declaration order. Config-level[vars]are unchanged. (#13322) - runtime symlinks:
latestand version-prefix links underinstalls/<tool>/that point at an install no longer eligible for a link (for example a directory left with anincompletemarker by an interrupted install) are now removed on rebuild instead of surviving indefinitely. Configured aliases, hand-made names, and absolute symlinks are left alone. (#13288) - npm: Semver pre-releases with numeric suffixes such as
1.3.1-3no longer claim thelatest,1, and1.3runtime symlinks or satisfy"latest"/prefix requests over the newest stable install; links an older mise already wrote are cleaned up on the next install. An exact request or theprereleaseoption still selects them. (#13272 by @pataar) - lockfile:
mise lock --globalon amise.locksymlinked into a dotfiles repository now keeps native dependency sidecars beside the target lockfile, somise install --lockedworks from a fresh checkout. If you used this layout on 2026.9.7 through 2026.9.10 and see missing sidecars, runmise lock --globalagain to repair the pointers. (#13268 by @nettlesh) - lockfile: With
lockfile_mode = "generate",mise unusenow removes the tool's entry frommise.lockand its.mise/locks/...sidecar immediately rather than leaving them until the nextmise installormise lock. Merge mode is unchanged. (#13304) - conda: Commands from
conda:packages that have nothing to activate (noactivate.dscripts, no dependency executables, no script entry points) are now plain symlinks instead of shell launchers, so tools likeconda:ripgreporconda:ghno longer prepend the conda prefix to thePATHof every child process and skip the extra shell. Packages that need activation keep their launcher; Windows is unchanged. A relativeMISE_DATA_DIRis also handled. Existing installs keep their current entries until reinstalled withmise install --force conda:<pkg>. (#13305) - backends: A tool's
postinstallhook now receives pre-tools[env]from the config on every backend (http, aqua, github, cargo, npm, core tools), not only for asdf plugins, and a hook that changes an env input is visible to hooks ordered after it. (#13316) - github: Tools whose release tags repeat the configured
version_prefix(taga-a-1.2.3withversion_prefix = "a-", listed asa-1.2.3) can now be installed;prefix + versionis tried first so every listed version round-trips to its tag. If a repo publishes botha-1.2.3anda-a-1.2.3, requestinga-1.2.3now resolves to the doubled tag. (#13317)
Changed
- brew-cask: Cask archives are downloaded concurrently at the configured
jobsconcurrency before the serial install pass, so--jobs/MISE_JOBSnow speed up cask-heavy runs. Placement (mounting, swapping app bundles) remains serial. (#13282 by @waynehoover)
Security
- http: Artifact downloads now refuse a redirect that steps down from HTTPS to HTTP, matching the policy the remote-version client already applied; the error names which kind of request was refused. URLs that are plain HTTP to begin with are unaffected. (#13292)
- brew-cask: The fingerprint used to adopt or refuse an existing app bundle is now computed entirely through the verified directory descriptor (
fstatat/openat/readlinkat), so a path component swapped mid-check cannot make mise compare against a different tree than the one it will replace. Digests are unchanged, so existing receipts remain valid; large files are now hashed in-process, which can make adoption checks slower. (#13294)
Documentation
- The bootstrap packages guide is reorganized around choosing a manager, declaring packages, and the command reference, with a dedicated section for direct
macos-appdownloads and app ownership. (#13298) - The variables guide explains when
[vars]resolve and why a task-local override does not recompute a top-level var that already referenced it, with task templates as the way to defer a fragment. (#13323) - Task Arguments documents sharing flags between tasks with usage
flagset,use, andinclude, in both TOML and file tasks. (#13313)
New Contributors
- @pataar made their first contribution in #13272
Full Changelog: https://github.com/jdx/mise/compare/v2026.9.10...v2026.9.11
💚 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.