mise Skill
mise (pronounced "meez", short for mise-en-place) is a single static binary that does three jobs
that usually take three tools:
| Job |
Tools it replaces |
Where it lives in config |
| Manage tool/language versions per project |
asdf, nvm, rbenv, pyenv |
[tools] |
| Switch environment variables per directory |
direnv, dotenv |
[env] |
| Run project tasks |
make, npm scripts, just |
[tasks.*] + mise run |
Everything lives in one committed mise.toml. This skill enforces a consistent house style so
every project's mise config reads the same way, and treats mise.toml as source-controlled infra:
pinned, reviewable, reproducible.
Before you touch anything
mise.toml can execute code (via [tasks], env._.source, env._.file). Two habits keep that safe
and predictable:
- Verify mise is present and how it's wired: run
mise --version and mise doctor. doctor
tells you whether the shell is activated, whether shims are on PATH, and which config files load.
Never assume — the #1 class of mise bugs is "tool installed but not found", and it's almost always
an activation/shim issue, not a version issue.
- Trust before you run: mise refuses to evaluate a config in an untrusted directory. After
creating or editing a
mise.toml, mise trust in that directory (or add the path to
trusted_config_paths).
Per the operating rules here: any executable helper you add to a project ships as TypeScript run
with bun, never Python or npm/npx.
Choose a workflow
Route to the workflow file that matches the request. Each is a self-contained recipe — read it, then
follow it.
| The user wants to… |
Workflow |
| Stand up mise for a repo (tools + env + tasks from scratch) |
Workflows/SetupProject.md |
| Add or pin a tool, pick the right backend |
Workflows/AddTool.md |
| Define, wire, and run tasks |
Workflows/CreateTasks.md |
| Move an existing repo off asdf / nvm / direnv / make |
Workflows/MigrateToMise.md |
| Fix "tool not found" / wrong version / activation / trust |
Workflows/Troubleshoot.md |
Reach for Templates.md whenever you need a concrete starting mise.toml — copy the closest sample
and delete what doesn't apply rather than writing one from a blank page.
House style
These conventions are what the linter (Tools/lint.ts) checks. They exist because a mise.toml is a
contract the whole team (and CI, and future-you) reads — surprises in it are expensive.
- Pin real versions in committed config.
node = '24' or node = '24.3.0', not node = 'latest'.
latest means "whatever exists the day someone runs mise install" — it silently breaks
reproducibility, which is the entire reason to use mise. latest is fine for a throwaway
mise x, never for mise.toml. Global ~/.config/mise/config.toml is the one place lts/latest
is acceptable, because it's personal, not shared.
- Order sections top-down as a reader would want them:
[tools], then [env], then [tasks.*],
then [settings]. Tools define the world, env configures it, tasks act in it.
- Every task gets a
description. mise tasks is the project's command menu; an undescribed task
is a dead entry. One line, imperative ("Build the release binary").
- Secrets are redacted, never inlined. Load them from a git-ignored
.env/.env.json via
env._.file, or mark them redact = true. A literal token in a committed mise.toml is a leak.
- Personal overrides go in
mise.local.toml (git-ignored), not in the committed file. Keep the
shared config clean.
- Prefer
mise use over hand-editing for tools, because it installs and writes the pin in one
reviewable step — but hand-editing is fine and expected for env and tasks.
Best practices worth stating out loud
- Reproducibility is the point. If two teammates run
mise install and get different tool
versions, the config has failed at its one job. Pinning is not pedantry; it's the deliverable.
- Activation vs shims is the mental model that prevents most pain.
mise activate updates PATH
at your shell prompt — great interactively, invisible to scripts/IDEs/cron because they never hit a
new prompt. Shims (~/.local/share/mise/shims) are real files that work everywhere. When something
can't find a tool outside an interactive shell, the fix is shims or mise exec, not reinstalling.
See References/Configuration.md and Workflows/Troubleshoot.md.
sources/outputs turn tasks into a cheap build cache. A task that declares what it reads and
writes is skipped when nothing changed — make-style incrementality without make's footguns.
- Let mise own the versions, not the READMEs. Once
mise.toml pins the toolchain, delete the
"install node 24, python 3.12…" prose from onboarding docs and point at mise install. The config
is now the single source of truth; two sources drift.
Validate before you call it done
After writing or editing a mise.toml, lint it and prove it loads:
bun <skill-dir>/Tools/lint.ts path/to/mise.toml --strict # house-style + safety check
mise trust path/to/ # trust the dir if new
mise install # resolves + installs everything
mise ls # confirm the versions you expect are active
mise tasks # confirm tasks are listed with descriptions
<skill-dir> is this skill's directory (wherever this SKILL.md lives — never assume a fixed
install path). --strict makes warnings fail the exit code too, so the lint works as a real gate.
A change isn't finished because the file parses — it's finished when mise install succeeds and the
tools/tasks you intended actually show up. Verify, don't assume.
Reference material
Load the reference that matches the depth you need — these hold the exhaustive detail so this file
stays scannable.
References/Configuration.md — mise.toml structure, config resolution & precedence, [settings],
trust, activation vs shims.
References/Tools.md — version strings, use/install/ls/upgrade/prune, backends (npm,
cargo, pipx, aqua, ubi, go, asdf/vfox).
References/Tasks.md — TOML & file tasks, depends, sources/outputs, usage argument specs,
parallelism.
References/Environments.md — [env], _.file/_.source/_.path, secrets & redaction, templates.
References/CliReference.md — every command you reach for, grouped by purpose.
1---2name: mise3description: Set up, configure, and maintain development environments with `mise` (mise-en-place) — the polyglot tool/version manager, per-directory environment switcher, and task runner. ALWAYS use this skill when the user mentions mise, `mise.toml`, `.mise.toml`, `mise use`, `mise run`, pinning tool/language versions per project, an asdf / nvm / rbenv / pyenv / direnv replacement, a `.tool-versions` file, or wants project-scoped env vars and task automation in one config. Also trigger when scaffolding a dev environment for a repo, migrating from asdf/nvm/direnv/make to mise, adding a tool from a backend (npm, cargo, pipx, aqua, ubi/GitHub), or diagnosing "tool not found" / activation / shim problems. Covers house conventions, a sample-driven config template, workflows, a `mise.toml` best-practice linter, and a full CLI reference. NOT FOR system package management (apt/brew for OS libraries), Nix flakes, or make-style file-timestamp build graphs with complex dependency trees.4---5
6# mise Skill
7
8`mise` (pronounced "meez", short for *mise-en-place*) is a single static binary that does three jobs
9that usually take three tools:
10
11| Job | Tools it replaces | Where it lives in config |
12|-----|-------------------|--------------------------|
13| Manage tool/language versions per project | asdf, nvm, rbenv, pyenv | `[tools]` |
14| Switch environment variables per directory | direnv, dotenv | `[env]` |
15| Run project tasks | make, npm scripts, just | `[tasks.*]` + `mise run` |
16
17Everything lives in one committed `mise.toml`. This skill enforces a consistent **house style** so
18every project's mise config reads the same way, and treats `mise.toml` as source-controlled infra:
19pinned, reviewable, reproducible.
20
21## Before you touch anything
22
23`mise.toml` can execute code (via `[tasks]`, `env._.source`, `env._.file`). Two habits keep that safe
24and predictable:
25
261. **Verify mise is present and how it's wired**: run `mise --version` and `mise doctor`. `doctor`
27 tells you whether the shell is activated, whether shims are on `PATH`, and which config files load.
28 Never assume — the #1 class of mise bugs is "tool installed but not found", and it's almost always
29 an activation/shim issue, not a version issue.
302. **Trust before you run**: mise refuses to evaluate a config in an untrusted directory. After
31 creating or editing a `mise.toml`, `mise trust` in that directory (or add the path to
32 `trusted_config_paths`).
33
34Per the operating rules here: any executable helper you add to a project ships as **TypeScript run
35with `bun`**, never Python or npm/npx.
36
37## Choose a workflow
38
39Route to the workflow file that matches the request. Each is a self-contained recipe — read it, then
40follow it.
41
42| The user wants to… | Workflow |
43|--------------------|----------|
44| Stand up mise for a repo (tools + env + tasks from scratch) | `Workflows/SetupProject.md` |
45| Add or pin a tool, pick the right backend | `Workflows/AddTool.md` |
46| Define, wire, and run tasks | `Workflows/CreateTasks.md` |
47| Move an existing repo off asdf / nvm / direnv / make | `Workflows/MigrateToMise.md` |
48| Fix "tool not found" / wrong version / activation / trust | `Workflows/Troubleshoot.md` |
49
50Reach for `Templates.md` whenever you need a concrete starting `mise.toml` — copy the closest sample
51and delete what doesn't apply rather than writing one from a blank page.
52
53## House style
54
55These conventions are what the linter (`Tools/lint.ts`) checks. They exist because a `mise.toml` is a
56contract the whole team (and CI, and future-you) reads — surprises in it are expensive.
57
58- **Pin real versions in committed config.** `node = '24'` or `node = '24.3.0'`, not `node = 'latest'`.
59 `latest` means "whatever exists the day someone runs `mise install`" — it silently breaks
60 reproducibility, which is the entire reason to use mise. `latest` is fine for a throwaway
61 `mise x`, never for `mise.toml`. Global `~/.config/mise/config.toml` is the one place `lts`/`latest`
62 is acceptable, because it's personal, not shared.
63- **Order sections top-down as a reader would want them:** `[tools]`, then `[env]`, then `[tasks.*]`,
64 then `[settings]`. Tools define the world, env configures it, tasks act in it.
65- **Every task gets a `description`.** `mise tasks` is the project's command menu; an undescribed task
66 is a dead entry. One line, imperative ("Build the release binary").
67- **Secrets are redacted, never inlined.** Load them from a git-ignored `.env`/`.env.json` via
68 `env._.file`, or mark them `redact = true`. A literal token in a committed `mise.toml` is a leak.
69- **Personal overrides go in `mise.local.toml`** (git-ignored), not in the committed file. Keep the
70 shared config clean.
71- **Prefer `mise use` over hand-editing** for tools, because it installs *and* writes the pin in one
72 reviewable step — but hand-editing is fine and expected for env and tasks.
73
74## Best practices worth stating out loud
75
76- **Reproducibility is the point.** If two teammates run `mise install` and get different tool
77 versions, the config has failed at its one job. Pinning is not pedantry; it's the deliverable.
78- **Activation vs shims is the mental model that prevents most pain.** `mise activate` updates `PATH`
79 at your shell prompt — great interactively, invisible to scripts/IDEs/cron because they never hit a
80 new prompt. Shims (`~/.local/share/mise/shims`) are real files that work everywhere. When something
81 can't find a tool outside an interactive shell, the fix is shims or `mise exec`, not reinstalling.
82 See `References/Configuration.md` and `Workflows/Troubleshoot.md`.
83- **`sources`/`outputs` turn tasks into a cheap build cache.** A task that declares what it reads and
84 writes is skipped when nothing changed — make-style incrementality without make's footguns.
85- **Let mise own the versions, not the READMEs.** Once `mise.toml` pins the toolchain, delete the
86 "install node 24, python 3.12…" prose from onboarding docs and point at `mise install`. The config
87 is now the single source of truth; two sources drift.
88
89## Validate before you call it done
90
91After writing or editing a `mise.toml`, lint it and prove it loads:
92
93```bash
94bun <skill-dir>/Tools/lint.ts path/to/mise.toml --strict # house-style + safety check
95mise trust path/to/ # trust the dir if new
96mise install # resolves + installs everything
97mise ls # confirm the versions you expect are active
98mise tasks # confirm tasks are listed with descriptions
99```
100
101`<skill-dir>` is this skill's directory (wherever this SKILL.md lives — never assume a fixed
102install path). `--strict` makes warnings fail the exit code too, so the lint works as a real gate.
103
104A change isn't finished because the file parses — it's finished when `mise install` succeeds and the
105tools/tasks you intended actually show up. Verify, don't assume.
106
107## Reference material
108
109Load the reference that matches the depth you need — these hold the exhaustive detail so this file
110stays scannable.
111
112- `References/Configuration.md` — `mise.toml` structure, config resolution & precedence, `[settings]`,
113 trust, activation vs shims.
114- `References/Tools.md` — version strings, `use`/`install`/`ls`/`upgrade`/`prune`, backends (npm,
115 cargo, pipx, aqua, ubi, go, asdf/vfox).
116- `References/Tasks.md` — TOML & file tasks, `depends`, `sources`/`outputs`, `usage` argument specs,
117 parallelism.
118- `References/Environments.md` — `[env]`, `_.file`/`_.source`/`_.path`, secrets & redaction, templates.
119- `References/CliReference.md` — every command you reach for, grouped by purpose.