mise · git:20260630.8d71e53 · 2026-06-30 · sha256 ae6de6f5fe7d9431
mise git:20260630.8d71e53B
Immutable. This exact content is served forever at /api/v1/blob/ae6de6f5fe7d9431.
---
name: mise
description: >-
Use when setting up or managing a project's toolchain, language runtimes, or
task running with mise (https://mise.jdx.dev/), when migrating a Makefile or
npm scripts to mise tasks, or when wiring mise into CI or container builds.
---
# mise
Manage a project's dev tools, language runtimes, and tasks through a single
committed `mise.toml`. The official docs at https://mise.jdx.dev/ cover the full
surface; this skill captures the *how we use it here* decisions, not the
reference.
## Quick start
One `mise.toml` per repo is the single source of truth for every tool, runtime,
and task. Pin versions explicitly, prefer built-in backends (`aqua`, `github`),
drive work through `mise run <task>`, and adopt in phases: host -> CI ->
containers.
## Core conventions
1. **Single source of truth** — one `mise.toml` at the repo root declares all
tools, runtimes, and tasks. Do not split version declarations between
`mise.toml` and `package.json` `packageManager`/corepack; remove the
duplicate once migrated.
2. **Pin explicitly** — choose each tool's version deliberately for
reproducibility: a major or channel for runtimes (`python = "3.14"`,
`java = "temurin-25"`, `node = "lts"`, which float the patch within a fixed
line), and `latest` for low-risk, fast-moving tools — especially linters
(`shellcheck = "latest"`, `actionlint = "latest"`, `uv = "latest"`), which
benefit from always running the newest rules.
3. **Tasks over Makefile/npm scripts** — define `[tasks]` with `run`,
`description`, and `depends` chains; run via `mise run <task>`. mise
orchestrates multi-tool workflows, not just Node.
4. **Built-in backends** — prefer `aqua:` and `github:` (built in,
provenance-verified). Avoid the deprecated `ubi:` backend and external
fetchers; migrate `ubi:owner/repo` -> `github:owner/repo` (same syntax).
5. **Idiomatic version files** — enable only when you need interop with existing
`.nvmrc` / `.node-version` / `package.json` `devEngines.runtime`:
`mise settings add idiomatic_version_file_enable_tools node`.
6. **Phased adoption** — host first, then CI, then containers; keep the old path
working until each phase is verified.
## mise.toml patterns
```toml
[tools]
shellcheck = "latest" # linter: latest for the newest rules
actionlint = "latest" # linter: latest for the newest rules
uv = "latest" # low-risk, fast-moving
node = "lts" # runtime: LTS channel, floats the patch
java = "temurin-25" # runtime: Temurin major, floats the patch
python = "3.14" # runtime: pin the minor line
[tasks.test]
description = "Run all test scripts"
run = "..."
[tasks.lint]
description = "Run all linters"
depends = ["lint-shell", "lint-actions"]
```
Translate a Makefile or npm script target to a task verbatim — preserve shell
semantics (pipes, loops, `$()`), keep the existing names, and add `depends` to
model the ordering the old target relied on.
## CI (GitHub Actions)
Use `jdx/mise-action@v4`; it reads the committed `mise.toml` and installs and
caches the pinned tools, replacing per-tool setup actions
(`actions/setup-python`, `astral-sh/setup-uv`, `raven-actions/actionlint`, …).
Run the actual work through tasks:
```yaml
- uses: jdx/mise-action@v4
- run: mise run test
- run: mise run lint
```
Scope a job to only the tools it needs with `install_args` — `with: { install_args:
"node aube" }` installs just those (versions still come solely from `mise.toml`), so
a JS job does not drag in unrelated toolchains like the dotnet SDK. The built-in
`cache: true` (on by default) caches the installed tool binaries.
## Containers
- Pin the mise binary by version and verify its sha256; do not pipe
`curl | bash` in production images.
- Pre-cache tools system-wide with `mise install --system` (lands in
`/usr/local/share/mise`) so a dropped-privilege runtime user (e.g. uid 1000)
can find them; ensure the result is world-readable.
## Gotchas
- **Untrusted `mise.toml`** — mise refuses to load a config it has not been
trusted to run; on a fresh checkout `mise install` and tasks silently no-op
until you run `mise trust` once in the repo. `jdx/mise-action` trusts the
config automatically, so this is a host-only first-run step.
- **Version-source fragmentation** — keeping `packageManager`/corepack alongside
`mise.toml` creates two version sources that drift. Consolidate to `mise.toml`.
- **`ubi:` deprecation** — it still works but warns; switch to the built-in
`github:` backend (same `owner/repo` syntax, with provenance verification).
- **Container tool visibility** — tools installed into root's home are invisible
to a uid-dropped runtime user; use `mise install --system` instead.
- **macOS Gatekeeper quarantine** — precompiled binaries mise downloads on macOS
(e.g. PHP) can be quarantined and refuse to run. On a Gatekeeper warning, clear
the attribute on the installed path:
`xattr -d com.apple.quarantine ~/.local/share/mise/installs/<tool>/<version>/...`.
## Related
- [`aube`](../aube/SKILL.md) — the Node.js package manager installed and pinned
through mise.