| name | mise |
| description | Use when working with mise - creating/editing mise.toml or .mise.toml files, defining tasks with usage field arguments, managing dev tools and environments, configuring hooks, or when user mentions mise configuration. |
Mise Comprehensive Skill
Table of Contents
STRICT ENFORCEMENT: Usage Field Required
This skill WILL NOT generate tasks with shell-native argument handling.
All task arguments MUST be defined using the usage field. This is non-negotiable.
REQUIRED Pattern
[tasks.deploy]
description = "Deploy to environment"
usage = 'arg "<env>" help="Target environment" choices "dev" "staging" "prod"'
run = 'deploy.sh ${usage_env?}'
#!/usr/bin/env bash
echo "Processing ${usage_input?} -> ${usage_output:-out.txt}"
BLOCKED Patterns
[tasks.bad]
run = 'deploy.sh $1 $2'
[tasks.also_bad]
run = 'process.sh "$@"'
[tasks.deprecated]
run = 'echo {{arg(name="x")}}'
Why This is Enforced
| Benefit | Description |
|---|
| Type Safety | Arguments validated before execution |
| Auto-completion | Shell completions generated automatically |
| Cross-platform | Works on bash, zsh, fish, PowerShell |
| Self-documenting | mise run --help shows all options |
| No Parsing Bugs | Eliminates shell quoting/escaping issues |
| Choices Validation | Invalid values rejected immediately |
Overview
mise is an all-in-one developer environment tool that manages:
- Dev tools - install and manage language runtimes, CLIs, and build tools (18 backends)
- Tasks - project-specific commands with argument handling, dependencies, caching
- Environments - manage env vars, profiles, dotenv files, secrets
- Hooks - run commands on directory changes, project enter/leave, tool install
Key Features:
- Parallel dependency building (concurrent by default)
- Last-modified and content-hash checking (avoid unnecessary rebuilds)
- File watching (
mise watch rebuilds on changes)
- Cross-platform argument handling via
usage spec
- Hierarchical configuration with profile support
- 18 tool backends (aqua, github, npm, cargo, pipx, go, etc.)
Task Definition Methods
TOML-Based Tasks (in mise.toml)
Simple Tasks
[tasks]
build = "cargo build"
test = "cargo test"
lint = "cargo clippy"
Detailed Tasks
[tasks.build]
description = "Build the CLI"
run = "cargo build"
[tasks.test]
description = "Run tests"
depends = ["build"]
run = "cargo test"
File-Based Tasks (executable scripts)
Place in mise-tasks/ or .mise/tasks/ directory. Files must be executable (chmod +x).
#!/usr/bin/env bash
cargo build
Supported directories:
mise-tasks/
.mise-tasks/
mise/tasks/
.mise/tasks/
.config/mise/tasks/
File tasks use #MISE or #USAGE comment headers for configuration.
Alternative header syntax (if formatters modify #MISE):
Task Grouping (Namespaces)
Subdirectories create namespaced tasks:
mise-tasks/
├── test/
│ ├── unit → test:unit
│ ├── integration → test:integration
│ └── e2e → test:e2e
└── lint/
├── eslint → lint:eslint
└── prettier → lint:prettier
Remote Tasks
Fetch tasks from external sources:
[tasks.build]
file = "https://example.com/build.sh"
[tasks.release]
file = "git::https://github.com/org/repo.git//scripts/release.sh?ref=v1.0.0"
Remote files are cached in MISE_CACHE_DIR.
Task Arguments - Usage Spec Reference
REMINDER: Always use the usage field. Never use $1, $@, or shell-native argument handling.
The usage field uses KDL-inspired syntax to define arguments, flags, and completions.
Positional Arguments (arg)
| Attribute | Type | Default | Description |
|---|
| (name) | string | required | "<name>" = required, "[name]" = optional. "<file>" triggers file completion, "<dir>" triggers dir completion. |
help | string | none | Short help text shown with -h |
long_help | string | none | Extended help text shown with --help |
default | string | none | Default value if not provided. default="" sets to empty string (different from unset). |
env | string | none | Environment variable that can provide this arg's value. Priority: CLI > env > default. |
var | boolean | #false | Variadic mode (accept multiple values). "<name>" requires 1+, "[name]" accepts 0+. |
var_min | integer | none | Minimum values when variadic |
var_max | integer | none | Maximum values when variadic |
choices | values | none | Restrict to enumerated set |
double_dash | string | none | "required", "optional", "automatic", "preserve" |
hide | boolean | #false | Exclude from help output |
Examples:
arg "<file>" help="Input file to process"
arg "[output]" default="out.txt" help="Output file"
arg "<files>" var=#true var_min=1 help="One or more files"
arg "<env>" choices "dev" "staging" "prod" help="Target environment"
arg "<args>..." double_dash="automatic" help="Pass-through arguments"
Variadic args in bash:
eval "files=($usage_files)"
for f in "${files[@]}"; do
echo "Processing: $f"
done
Flags (flag)
| Attribute | Type | Default | Description |
|---|
| (definition) | string | required | "-s --long" (boolean) or "-s --long <value>" (with value). Short flag optional. |
help | string | none | Short help text |
long_help | string | none | Extended help for --help |
default | string/bool | none | Default value. Boolean flags use #true/#false. |
env | string | none | Environment variable backing the flag |
global | boolean | #false | Available on all subcommands |
count | boolean | #false | Value = number of times used (e.g., -vvv = 3) |
var | boolean | #false | Flag repeatable, collecting values |
var_min | integer | none | Min values when var=#true |
var_max | integer | none | Max values when var=#true |
negate | string | none | Negative form (e.g., "--no-color"). Sets env var to false. |
choices | block | none | Restrict values to enumerated set |
hide | boolean | #false | Exclude from docs/completions |
required_if | string | none | Required if named flag is set |
required_unless | string | none | Required unless named flag is present |
overrides | string | none | If set, named flag's value is ignored |
Examples:
flag "-v --verbose" help="Enable verbose output"
flag "-f --force" help="Skip confirmation prompts"
flag "--port <port>" default="8080" help="Server port"
flag "--color" negate="--no-color" default=#true help="Enable colors"
flag "-d --debug" count=#true help="Debug level (-ddd for max)"
flag "--include <pattern>" var=#true help="Include patterns (repeatable)"
flag "--shell <shell>" { choices "bash" "zsh" "fish" }
flag "--file <file>" required_if="--dir" help="Required if --dir is set"
Count flags: -vvv sets $usage_verbose to 3. Short flags chain: -abc = -a -b -c.
Negate flags: flag "--color" negate="--no-color" default=#true — --no-color sets $usage_color to false.
Custom Completions (complete)
Provide dynamic tab-completion for arguments. Preferred over choices when values change.
complete "<arg_name>" run="<shell command outputting one value per line>"
Key rules:
- Must appear after the
arg it applies to
- Names must match exactly
- Do not combine with
choices on the same arg
Examples:
usage = '''
arg "<service>" help="Service name"
complete "service" run="ls -d infrastructure/*/application 2>/dev/null | sed 's|infrastructure/||;s|/application||'"
arg "<environment>" help="Target environment"
complete "environment" run="ls infrastructure/${usage_service}/application/env/ 2>/dev/null | sed 's/.tfvars//'"
'''
With descriptions:
complete "plugin" run="mise plugins ls" descriptions=#true
Output format: value:description per line.
choices vs complete:
| Feature | choices | complete |
|---|
| Values | Hardcoded in spec | Dynamic from command |
| Validation | Rejects invalid input | Tab-completion only |
| Maintenance | Must edit to add options | Auto-discovers new options |
| Best for | Stable enums (yes/no, log levels) | File/directory-derived values |
Accessing Arguments in Scripts
Environment variables (prefixed with usage_):
| Definition | Environment Variable |
|---|
arg "<file>" | $usage_file |
arg "[output]" | $usage_output |
flag "-v --verbose" | $usage_verbose |
flag "--dry-run" | $usage_dry_run |
flag "-o --output <file>" | $usage_output |
Naming rules: usage_ prefix, hyphens to underscores, lowercase, long name used.
Bash variable expansion patterns:
| Pattern | Use Case |
|---|
${var?} | Required args - fail if missing |
${var:-default} | Optional with fallback |
${var:?msg} | Required with custom error |
${var:+value} | Conditional (if set, use value) |
Values by type:
| Type | Present | Absent |
|---|
| Boolean flag | "true" | unset (or "false" with default=#false) |
| Count flag | "1", "2", etc. | "0" |
| Value flag/arg | the string value | unset or default |
| Variadic | shell-escaped space-separated | unset or empty |
Critical distinction: default="" makes variable SET to empty string. No default + not provided = UNSET.
echo "Deploying to ${usage_environment?}"
clean="${usage_clean:-false}"
docker build ${usage_verbose:+--verbose} .
if [ -n "${usage_dry_run:-}" ]; then
echo "Dry run mode"
fi
eval "files=($usage_files)"
File Task Headers
#!/usr/bin/env bash
echo "Deploying to ${usage_environment?}"
Supported shebangs: bash, node, python, deno, pwsh, fish, zsh.
Task Configuration Reference
All Task Fields
Core Execution
| Field | Type | Default | Description |
|---|
run | string | string[] | object[] | — | Command(s) to execute. Supports structured array (see below). |
run_windows | same as run | — | Windows-specific override |
file | string | — | External script path (local, HTTP, or Git URL) |
shell | string | — | Interpreter (e.g., "bash -c", "node -e") |
usage | string | — | Usage spec for arguments/flags |
Metadata
| Field | Type | Default | Description |
|---|
description | string | — | Task help text |
alias | string | string[] | — | Alternative name(s) |
hide | bool | false | Exclude from listings |
Dependencies
| Field | Type | Default | Description |
|---|
depends | string | string[] | object[] | — | Tasks to run BEFORE (supports structured objects) |
depends_post | string | string[] | object[] | — | Tasks to run AFTER |
wait_for | string | string[] | object[] | — | Wait for tasks without adding as deps |
Environment & Tools
| Field | Type | Default | Description |
|---|
env | table | — | Task-specific env vars (NOT passed to depends). Supports age-encrypted values. |
tools | table | — | Tools to install before running |
Execution Context
| Field | Type | Default | Description |
|---|
dir | string | {{config_root}} | Working directory. Use {{cwd}} for user's cwd. |
raw | bool | false | Direct stdin/stdout connection (disables parallel execution) |
Output Control
| Field | Type | Default | Description |
|---|
quiet | bool | false | Suppress mise output |
silent | bool | "stdout" | "stderr" | false | Suppress all/specific output |
Caching
| Field | Type | Default | Description |
|---|
sources | string | string[] | — | Input files (glob patterns) |
outputs | string | string[] | {auto: true} | — | Generated files. Use {auto = true} for implicit tracking. |
Safety
| Field | Type | Default | Description |
|---|
confirm | string | — | Prompt before running. Supports Tera templates with usage.*. |
Timeout & Inheritance
| Field | Type | Default | Description |
|---|
timeout | string | — | Max execution duration (e.g., "30s", "5m"). Overrides global task_timeout. |
extends | string | — | Template task to inherit configuration from. |
Structured run Array
Mix inline scripts with task references, including parallel sub-task execution:
[tasks.pipeline]
run = [
{ task = "lint" },
{ tasks = ["test", "typecheck"] },
"echo 'All checks passed!'",
]
Structured depends with Args/Env
Pass arguments and environment variables to dependencies:
[tasks.deploy]
depends = [
{ task = "build", args = ["--release"], env = { RUSTFLAGS = "-C opt-level=3" } }
]
run = "./deploy.sh"
Env vars passed to dependencies are scoped to that dependency only.
Task Inheritance (extends)
A task can inherit configuration from another task:
[tasks._base_deploy]
hide = true
depends = ["build", "test"]
env = { DEPLOY_TIMESTAMP = "{{now()}}" }
tools = { node = "22" }
[tasks.deploy-staging]
extends = "_base_deploy"
env = { DEPLOY_ENV = "staging" }
run = "./scripts/deploy.sh staging"
[tasks.deploy-prod]
extends = "_base_deploy"
confirm = "Deploy to production?"
env = { DEPLOY_ENV = "production" }
run = "./scripts/deploy.sh production"
Global Task Configuration
[task_config] Section
[task_config]
dir = "{{cwd}}"
includes = [
"tasks/*.toml",
".mise/tasks/",
"git::https://github.com/org/tasks?ref=v1"
]
[vars] Section
Shared variables between tasks (NOT environment variables):
[vars]
project_name = "myapp"
version = "1.0.0"
registry = "ghcr.io/myorg"
[vars._.file]
path = "vars.toml"
[tasks.build]
run = "echo Building {{vars.project_name}} v{{vars.version}}"
Vars are accessed via {{vars.key_name}} Tera templates. They are not passed as environment variables.
Global Task Settings
| Setting | Type | Default | Description |
|---|
task_output | string | "prefix" | Output mode: prefix, interleave, keep-order, replacing, timed, quiet, silent |
task_timeout | string | none | Default timeout (e.g., "30m") |
task_timings | bool | false | Show elapsed time per task |
task_skip | string[] | [] | Tasks to skip by default |
task_skip_depends | bool | false | Skip dependencies |
task_run_auto_install | bool | true | Auto-install missing tools |
task_show_full_cmd | bool | false | Disable command truncation in output |
task_disable_paths | string[] | [] | Paths to exclude from task discovery |
task_remote_no_cache | bool | false | Always fetch latest remote tasks |
task.source_freshness_hash_contents | bool | false | Use blake3 content hashing instead of mtime |
task.source_freshness_equal_mtime_is_fresh | bool | false | Equal mtime = fresh |
jobs | int | 8 | Max concurrent task execution |
Running Tasks (CLI)
Commands
| Command | Description |
|---|
mise run <task> / mise r <task> | Execute task |
mise <task> | Shorthand (if no command conflict) |
mise tasks / mise tasks ls | List all tasks |
mise tasks --hidden | Include hidden tasks |
mise tasks deps | Show dependency tree |
mise tasks deps --dot | DOT format for Graphviz |
mise tasks info <task> | Show task details |
mise tasks add <name> -- <cmd> | Create task via CLI |
mise watch <task> / mise w <task> | Watch and re-run on file changes |
Execution Flags
| Flag | Description |
|---|
-j, --jobs N | Parallel job limit (default: 4) |
-f, --force | Ignore source/output caching |
-n, --dry-run | Preview without executing |
-o, --output MODE | prefix, interleave, keep-order, replacing, timed, quiet, silent |
-r, --raw | Direct stdin/stdout/stderr |
-c, --continue-on-error | Continue running tasks even if one fails |
-s, --shell SHELL | Shell spec (default: sh -c -o errexit -o pipefail) |
-t, --tool TOOL@VERSION | Additional tools beyond mise.toml |
--timings | Show elapsed time per task |
--timeout DURATION | Task timeout (e.g., 30s, 5m) |
--fresh-env | Bypass environment cache |
--skip-deps | Run only specified tasks, skip dependencies |
--no-cache | Skip cache on remote tasks |
--no-prepare | Skip automatic dependency preparation |
Parallel Tasks and Wildcards
mise run test:*
mise run lint:**
mise run {build,test}
mise run lint ::: test ::: check
mise run cmd1 arg1 ::: cmd2 arg2
Default Task
[tasks.default]
depends = ["build", "test"]
run = "echo 'Ready!'"
Task Dependencies and Caching
Dependencies
[tasks.deploy]
depends = ["build", "test", "lint"]
depends_post = ["notify"]
wait_for = ["db:migrate"]
Caching with sources/outputs
[tasks.build]
sources = ["Cargo.toml", "src/**/*.rs"]
outputs = ["target/release/myapp"]
run = "cargo build --release"
Auto outputs:
[tasks.build]
sources = ["src/**/*.rs"]
outputs = { auto = true }
run = "cargo build"
Redactions (Experimental)
Hide sensitive values from task output:
redactions = ["API_KEY", "PASSWORD", "SECRETS_*"]
Dev Tools Management
Backends Overview
mise supports 18 backend types. Recommended priority order:
| Priority | Backend | Description |
|---|
| 1 | aqua | Most features, best security (cosign/SLSA/attestation). No plugins needed. |
| 2 | github | GitHub releases with auto OS/arch detection |
| 3 | gitlab | GitLab releases |
| 4 | forgejo | Forgejo/Codeberg releases |
| 5 | http | Direct HTTP/HTTPS downloads with URL templating |
| 6 | s3 | S3/MinIO (experimental) |
| 7 | pipx | Python CLIs in isolated environments |
| 8 | npm | Node packages |
| 9 | go | Go packages (requires compilation) |
| 10 | cargo | Rust packages (requires compilation) |
| 11 | gem | Ruby gems |
| 12 | dotnet | .NET tools (experimental) |
| 13 | conda | Conda packages (experimental) |
| 14 | spm | Swift packages (experimental) |
| 15 | vfox | vfox plugins (cross-platform, Windows) |
| 16 | asdf | asdf plugins (legacy, no Windows) |
TOML Syntax for Tools
[tools]
node = "22"
python = "3.12"
ruby = "latest"
python = ["3.12", "3.11"]
node = { version = "22", postinstall = "corepack enable" }
python = { version = "3.11", os = ["linux", "macos"] }
ripgrep = { version = "latest", os = ["linux", "macos"] }
"aqua:BurntSushi/ripgrep" = "latest"
"github:cli/cli" = "latest"
"npm:prettier" = "latest"
"pipx:psf/black" = "latest"
"cargo:eza" = "latest"
"go:github.com/DarthSim/hivemind" = "latest"
Version formats:
| Format | Example | Description |
|---|
| Exact | "20.0.0" | Specific version |
| Prefix | "20" | Latest matching prefix |
| Latest | "latest" | Most recent stable |
ref:<SHA> | "ref:abc123" | Compile from git ref |
path:<PATH> | "path:/opt/node" | Use custom binary |
sub-<N>:<BASE> | "sub-1:latest" | N versions behind base |
Per-Tool Options
Every tool supports these options regardless of backend:
| Option | Type | Description |
|---|
version | string | Tool version |
os | string[] | Restrict to OS: "linux", "macos", "windows" |
install_env | table | Environment variables during installation |
postinstall | string | Command after installation. MISE_TOOL_INSTALL_PATH available. |
Backend-Specific Configuration
GitHub Backend Options
[tools."github:cli/cli"]
version = "latest"
asset_pattern = "gh_*_linux_x64.tar.gz"
bin = "gh"
filter_bins = "gh"
no_app = true
HTTP Backend
[tools."http:my-tool"]
version = "1.0.0"
[tools."http:my-tool".platforms]
macos-x64 = { url = "https://example.com/tool-macos-x64.tar.gz", checksum = "sha256:..." }
linux-x64 = { url = "https://example.com/tool-linux-x64.tar.gz", checksum = "sha256:..." }
URL template variables: {{ version }}, {{ os() }}, {{ arch() }}, {{ os_family() }}
OS/arch remapping: {{ os(macos="darwin") }}, {{ arch(x64="amd64") }}
Cargo Backend
[tools]
"cargo:eza" = "latest"
"cargo:cargo-edit" = { version = "latest", features = "add" }
Settings: cargo.binstall = true (use precompiled binaries, default), cargo.binstall_only = false.
Pipx Backend
[tools]
"pipx:black" = "latest"
"pipx:harlequin" = { version = "latest", extras = "postgres,s3" }
"pipx:ansible" = { version = "latest", uvx = false }
Shims and Aliases
Shims location: ~/.local/share/mise/shims
eval "$(mise activate zsh --shims)"
eval "$(mise activate zsh)"
Best practice: Use both — shims in profile for non-interactive, PATH activation in rc for interactive.
Tool aliases (remap to different backend):
[tool_alias]
node = 'asdf:company/our-custom-node'
[tool_alias.node.versions]
lts = '22'
Shell aliases:
[shell_alias]
ll = "ls -la"
gs = "git status"
CLI Commands for Tools
mise use node@22
mise use -g node@22
mise install node@20
mise install
mise ls
mise ls-remote node
mise which node
mise x python@3.12 -- script.py
mise reshim
mise registry
Environment Configuration
Basic Variables
[env]
NODE_ENV = 'production'
DEBUG = 'app:*'
PORT = 3000
UNWANTED_VAR = false
mise set NODE_ENV=development
mise set
mise unset NODE_ENV
mise env
mise env --json
mise env --dotenv
Special Directives (env._)
_.path — Prepend to PATH
[env]
_.path = ["tools/bin", "{{config_root}}/scripts"]
_.path = { path = ["{{env.GEM_HOME}}/bin"], tools = true }
_.file — Load from .env/json/yaml files
[env]
_.file = '.env'
_.file = ['.env', '.env.local', '.env.{{env.MISE_ENV}}']
_.file = { path = ".secrets.yaml", redact = true }
_.source — Source shell scripts
[env]
_.source = "./setup-env.sh"
_.source = { path = "my/env.sh", tools = true }
Profiles (MISE_ENV)
Profiles enable environment-specific config files:
MISE_ENV=staging mise run deploy
This loads mise.staging.toml in addition to mise.toml. Config file order:
mise.toml (base)
mise.staging.toml (profile overlay)
mise.staging.local.toml (local overrides, gitignored)
Important: MISE_ENV cannot be set in mise.toml — it must be in .miserc.toml, an env var, or CLI flag because it determines which config files to load.
Required and Redacted Variables
[env]
DATABASE_URL = { required = "Set postgres connection string" }
API_KEY = { value = "secret_key_here", redact = true }
redactions = ["*_TOKEN", "SECRET_*", "API_*"]
Templates (Tera)
mise.toml values support Tera templates:
[env]
PROJECT_DIR = "{{config_root}}"
LOG_FILE = "{{config_root}}/logs/{{now() | date(format='%Y-%m-%d')}}.log"
NODE_PATH = "{{env.npm_config_prefix}}/lib/node_modules"
Available template variables:
| Variable | Description |
|---|
env.* | Current environment variables |
config_root | Directory containing mise.toml |
cwd | Current working directory |
mise_bin | Path to mise binary |
mise_pid | Process ID |
xdg_cache_home | XDG cache directory |
xdg_config_home | XDG config directory |
xdg_data_home | XDG data directory |
xdg_state_home | XDG state directory |
Key Tera functions:
| Function | Description |
|---|
exec(command="cmd") | Execute shell command, return stdout |
arch() | System architecture |
os() | Operating system |
os_family() | OS family (unix/windows) |
num_cpus() | CPU count |
now() | Current datetime |
get_env(name, default) | Get env var with fallback |
chomp(str) | Remove trailing newline |
Key Tera filters:
| Filter | Description |
|---|
lower, upper, capitalize | Case transforms |
trim, replace(from, to) | String manipulation |
split(pat), join(sep) | Array operations |
basename, dirname, extname | Path operations |
hash, hash_file | SHA256/BLAKE3 hashing |
absolute, canonicalize | Path resolution |
kebabcase, snakecase, uppercamelcase | Case conversion |
Shell-style variable expansion (requires env_shell_expand = true):
[settings]
env_shell_expand = true
[env]
LD_LIBRARY_PATH = "$MY_LIB:$LD_LIBRARY_PATH"
Hooks and Watchers
Hook Types
| Hook | Trigger | Requires mise activate? |
|---|
cd | Directory changes | Yes |
enter | Enter a project (once) | Yes |
leave | Leave a project (once) | Yes |
preinstall | Before tool installation | No |
postinstall | After tool installation | No |
Syntax
[hooks]
cd = "echo 'changed directory'"
enter = "echo 'entered project'"
leave = "echo 'left project'"
preinstall = "echo 'about to install'"
postinstall = "echo 'installed'"
enter = ["echo 'first'", "echo 'second'"]
[hooks.enter]
shell = "bash"
script = "source completions.sh"
Watch Files
[[watch_files]]
patterns = ["src/**/*.rs"]
run = "cargo fmt"
Sets MISE_WATCH_FILES_MODIFIED env var. Requires watchexec.
Hook Environment Variables
All hooks receive: MISE_ORIGINAL_CWD, MISE_PROJECT_ROOT, MISE_PREVIOUS_DIR (cd hooks).
Postinstall receives: MISE_INSTALLED_TOOLS (JSON array), MISE_TOOL_NAME, MISE_TOOL_VERSION, MISE_TOOL_INSTALL_PATH.
Configuration and Settings
File Hierarchy
Config files in precedence order (highest first):
mise.local.toml
mise.toml
mise/config.toml
.mise/config.toml
.config/mise.toml
.config/mise/config.toml
.config/mise/conf.d/*.toml (alphabetical)
Global: ~/.config/mise/config.toml
System: /etc/mise/config.toml
Legacy: .tool-versions (asdf-compatible)
mise searches upward from cwd to root (or MISE_CEILING_PATHS). Merge behavior:
- Tools: Additive with overrides
- Env vars: Additive with overrides
- Tasks: Completely replaced per task name
- Settings: Additive with overrides
Key Settings Reference
[settings]
jobs = 8
experimental = false
task_output = "prefix"
task_timeout = "10m"
task_timings = true
task_skip = ["slow-task"]
task_skip_depends = false
env_shell_expand = true
env_cache = false
env_cache_ttl = "1h"
auto_install = true
disable_backends = ["asdf"]
pin = false
lockfile = true
paranoid = false
gpg_verify = false
fetch_remote_versions_cache = "1h"
http_timeout = "30s"
[settings.node]
corepack = false
compile = false
[settings.python]
uv_venv_auto = false
compile = false
[settings.aqua]
cosign = true
slsa = true
Minimum Version
min_version = '2024.11.1'
min_version = { soft = '2024.11.1' }
min_version = { hard = '2024.11.1', soft = '2024.9.0' }
Automatic Environment Variables
Tasks automatically receive:
| Variable | Description |
|---|
MISE_ORIGINAL_CWD | Original working directory |
MISE_CONFIG_ROOT | Directory containing mise.toml |
MISE_PROJECT_ROOT | Project root directory |
MISE_TASK_NAME | Current task name |
MISE_TASK_DIR | Task script directory |
MISE_TASK_FILE | Full path to task script |
Prepare Feature (Experimental)
Ensures dependencies are installed before task execution.
export MISE_EXPERIMENTAL=1
mise prepare
[prepare.npm]
auto = true
[prepare.custom]
sources = ["schema/*.graphql"]
outputs = ["src/generated/"]
run = "npm run codegen"
Built-in providers: npm, yarn, pnpm, bun, go, pip, poetry, uv, bundler, composer.
Monorepo Tasks (Experimental)
experimental_monorepo_root = true
Requires MISE_EXPERIMENTAL=1.
mise //projects/frontend:build
mise :build
mise '//projects/frontend:*'
mise //...:test
Settings:
[settings.task]
monorepo_depth = 5
monorepo_exclude_dirs = ["dist", "node_modules"]
monorepo_respect_gitignore = true
Best Practices
DO
- Always use
usage field for task arguments
- Use
${var?} for required args to fail early
- Set
description for discoverability
- Use
sources/outputs for cacheable tasks
- Use
depends for task ordering
- Use
confirm for destructive operations
- Use
choices for stable enums, complete for dynamic/filesystem-derived values
- Group related tasks with namespaces (e.g.,
test:unit, test:e2e)
- Use
mise.local.toml for personal overrides (gitignored)
- Prefer aqua backend for security (cosign/SLSA verification)
- Use
env._.file for dotenv loading instead of MISE_ENV_FILE
- Redact sensitive values with
redact = true
- Use templates for dynamic values instead of hardcoding paths
- Use
extends to share config between similar tasks
DON'T
- Use
$1, $2, $@, $* for arguments
- Use
$args in PowerShell
- Use inline
{{arg(name="x")}} syntax (deprecated, removed 2026.11)
- Forget to quote glob patterns in sources
- Set env vars in
env that deps need (they don't inherit — use structured depends with env)
- Use
raw = true unless interactive input needed
- Set
MISE_ENV in mise.toml (it determines which files to load)
- Manually add executables to shims directory (
mise reshim removes them)
- Use
MISE_RAW=1 without knowing it sets MISE_JOBS=1
Complete Task Example
[tasks.deploy]
description = "Deploy application to environment"
alias = "d"
depends = ["build", "test"]
usage = '''
arg "<env>" choices "dev" "staging" "prod" help="Target environment"
flag "-f --force" help="Skip confirmation"
flag "--dry-run" help="Preview only"
'''
env = { DEPLOY_TIMESTAMP = "{{now()}}" }
tools = { node = "22" }
sources = ["dist/**/*"]
timeout = "5m"
confirm = "Deploy to {{usage.env}}?"
run = '''
#!/usr/bin/env bash
set -euo pipefail
if [ -n "${usage_dry_run:-}" ]; then
echo "DRY RUN: Would deploy to ${usage_env?}"
exit 0
fi
./scripts/deploy.sh "${usage_env?}"
'''
Complete File Task Example
#!/usr/bin/env bash
set -euo pipefail
direction="${usage_direction?}"
count="${usage_count:-1}"
if [ -n "${usage_dry_run:-}" ]; then
echo "Would run $count migration(s) $direction"
exit 0
fi
migrate "$direction" -n "$count"
Complete Dev Tools + Env Example
min_version = "2024.11.1"
[settings]
jobs = 8
task_output = "interleave"
task_timings = true
env_shell_expand = true
[tools]
node = "22"
python = { version = "3.12", postinstall = "pip install -r requirements.txt" }
"aqua:BurntSushi/ripgrep" = "latest"
"npm:prettier" = "latest"
[env]
NODE_ENV = "development"
DATABASE_URL = { required = "Set postgres connection string" }
API_KEY = { value = "{{env.API_KEY}}", redact = true }
_.path = ["./node_modules/.bin", "{{config_root}}/scripts"]
_.file = [".env", ".env.local"]
[hooks]
enter = "echo 'Welcome to {{vars.project_name}}'"
[vars]
project_name = "myapp"
[tasks.dev]
description = "Start development server"
depends = ["build"]
tools = { node = "22" }
run = "npm run dev"
[tasks.build]
description = "Build project"
sources = ["src/**/*.ts", "tsconfig.json"]
outputs = ["dist/**/*"]
run = "tsc --build"
[tasks.test]
description = "Run tests"
depends = ["build"]
run = "vitest run"