mise
Mise Comprehensive Skill
Table of Contents
- STRICT ENFORCEMENT: Usage Field Required
- Overview
- Task Definition Methods
- Task Arguments - Usage Spec Reference
- Task Configuration Reference
- Running Tasks (CLI)
- Task Dependencies and Caching
- Dev Tools Management
- Environment Configuration
- Hooks and Watchers
- Configuration and Settings
- Prepare Feature (Experimental)
- Monorepo Tasks (Experimental)
- Best Practices
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
#MISE description="Process files"
#USAGE arg "<input>" help="Input file"
#USAGE arg "[output]" default="out.txt" help="Output file"
echo "Processing ${usage_input?} -> ${usage_output:-out.txt}"
BLOCKED Patterns
# BLOCKED: Bash positional arguments
[tasks.bad]
run = 'deploy.sh $1 $2'
# BLOCKED: Bash special variables
[tasks.also_bad]
run = 'process.sh "$@"'
# BLOCKED: Inline Tera templates (deprecated, removed 2026.11)
[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 watchrebuilds on changes) - Cross-platform argument handling via
usagespec - 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
#MISE description="Build the CLI"
#MISE depends=["lint"]
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):
# [MISE] description="Build"
# [MISE] depends=["lint"]
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:
# Values are shell-escaped string in usage_files
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
argit applies to - Names must match exactly
- Do not combine with
choiceson the samearg
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.
# Required arg - error if not provided
echo "Deploying to ${usage_environment?}"
# Optional with default
clean="${usage_clean:-false}"
# Conditional flag forwarding
docker build ${usage_verbose:+--verbose} .
# Boolean flag check
if [ -n "${usage_dry_run:-}" ]; then
echo "Dry run mode"
fi
# Variadic to array
eval "files=($usage_files)"
File Task Headers
#!/usr/bin/env bash
#MISE description="Deploy application"
#USAGE arg "<environment>" help="Environment" {
#USAGE choices "dev" "prod"
#USAGE }
#USAGE flag "-f --force" help="Skip confirmation"
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" }, # run lint (with its dependencies)
{ tasks = ["test", "typecheck"] }, # run test and typecheck in parallel
"echo 'All checks passed!'", # then run a script
]
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}}" # Default working directory for all tasks
includes = [
"tasks/*.toml", # Local task files
".mise/tasks/", # Task directory
"git::https://github.com/org/tasks?ref=v1" # Remote tasks
]
[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" # Load vars from external file
[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:* # All test:* tasks
mise run lint:** # All nested lint tasks
mise run {build,test} # Multiple specific tasks
mise run lint ::: test ::: check # Parallel task groups with :::
mise run cmd1 arg1 ::: cmd2 arg2 # Parallel with separate args
Default Task
[tasks.default]
depends = ["build", "test"]
run = "echo 'Ready!'"
Task Dependencies and Caching
Dependencies
[tasks.deploy]
depends = ["build", "test", "lint"] # Run before (parallel by default)
depends_post = ["notify"] # Run after
wait_for = ["db:migrate"] # Wait if running, don't add
Caching with sources/outputs
[tasks.build]
sources = ["Cargo.toml", "src/**/*.rs"]
outputs = ["target/release/myapp"]
run = "cargo build --release"
# Skips if sources unchanged and outputs exist
Auto outputs:
[tasks.build]
sources = ["src/**/*.rs"]
outputs = { auto = true } # Implicit tracking via task hash
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]
# Simple version
node = "22"
python = "3.12"
ruby = "latest"
# Multiple versions
python = ["3.12", "3.11"]
# With options
node = { version = "22", postinstall = "corepack enable" }
python = { version = "3.11", os = ["linux", "macos"] }
ripgrep = { version = "latest", os = ["linux", "macos"] }
# Explicit backend
"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" # Match specific release asset
bin = "gh" # Rename binary
filter_bins = "gh" # Only expose specific bins
no_app = true # Skip macOS .app bundles
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 } # Disable uv
Shims and Aliases
Shims location: ~/.local/share/mise/shims
# Shim mode (non-interactive shells)
eval "$(mise activate zsh --shims)" # in ~/.zprofile
# PATH mode (interactive shells)
eval "$(mise activate zsh)" # in ~/.zshrc
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 # Install + activate + write to mise.toml
mise use -g node@22 # Write to global config
mise install node@20 # Install without activation
mise install # Install all configured tools
mise ls # List installed
mise ls-remote node # List available versions
mise which node # Show real binary path
mise x python@3.12 -- script.py # Run with specific tool
mise reshim # Rebuild shims
mise registry # List all available tools
Environment Configuration
Basic Variables
[env]
NODE_ENV = 'production'
DEBUG = 'app:*'
PORT = 3000
# Unset a variable
UNWANTED_VAR = false
mise set NODE_ENV=development # Set via CLI
mise set # View all
mise unset NODE_ENV # Remove
mise env # Export all
mise env --json # Export as JSON
mise env --dotenv # Export as dotenv
Special Directives (env._)
_.path — Prepend to PATH
[env]
_.path = ["tools/bin", "{{config_root}}/scripts"]
_.path = { path = ["{{env.GEM_HOME}}/bin"], tools = true } # Lazy eval
_.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]
# Required — error if not set
DATABASE_URL = { required = "Set postgres connection string" }
# Redacted — hidden from output
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'"
# Multiple hooks
enter = ["echo 'first'", "echo 'second'"]
# Shell hooks (execute in current shell context)
[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.tomlmise.tomlmise/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]
# Execution
jobs = 8 # Concurrent jobs
experimental = false # Enable experimental features
# Task defaults
task_output = "prefix" # prefix|interleave|keep-order|replacing|timed|quiet|silent
task_timeout = "10m" # Default task timeout
task_timings = true # Show elapsed time
task_skip = ["slow-task"] # Tasks to skip
task_skip_depends = false # Skip dependencies
# Environment
env_shell_expand = true # Enable $VAR expansion
env_cache = false # Cache computed environment
env_cache_ttl = "1h" # Cache TTL
# Tool management
auto_install = true # Auto-install missing tools
disable_backends = ["asdf"] # Disable backends
pin = false # Default --pin for mise use
lockfile = true # Read/update lockfiles
# Security
paranoid = false # Extra-secure behavior
gpg_verify = false # Verify GPG signatures
# Performance
fetch_remote_versions_cache = "1h" # Version cache
http_timeout = "30s" # HTTP timeout
# Node-specific
[settings.node]
corepack = false # Enable corepack
compile = false # Compile from source
# Python-specific
[settings.python]
uv_venv_auto = false # Auto-create venv with uv
compile = false # Compile from source
# Aqua security
[settings.aqua]
cosign = true # Verify Cosign signatures
slsa = true # Verify SLSA provenance
Minimum Version
min_version = '2024.11.1' # Hard (errors)
min_version = { soft = '2024.11.1' } # Soft (warns)
min_version = { hard = '2024.11.1', soft = '2024.9.0' } # Both
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)
# Root mise.toml
experimental_monorepo_root = true
Requires MISE_EXPERIMENTAL=1.
mise //projects/frontend:build # Absolute path from root
mise :build # Task in current config_root
mise '//projects/frontend:*' # All tasks in frontend
mise //...:test # Test task in all projects
Settings:
[settings.task]
monorepo_depth = 5
monorepo_exclude_dirs = ["dist", "node_modules"]
monorepo_respect_gitignore = true
Best Practices
DO
- Always use
usagefield for task arguments - Use
${var?}for required args to fail early - Set
descriptionfor discoverability - Use
sources/outputsfor cacheable tasks - Use
dependsfor task ordering - Use
confirmfor destructive operations - Use
choicesfor stable enums,completefor dynamic/filesystem-derived values - Group related tasks with namespaces (e.g.,
test:unit,test:e2e) - Use
mise.local.tomlfor personal overrides (gitignored) - Prefer aqua backend for security (cosign/SLSA verification)
- Use
env._.filefor dotenv loading instead ofMISE_ENV_FILE - Redact sensitive values with
redact = true - Use templates for dynamic values instead of hardcoding paths
- Use
extendsto share config between similar tasks
DON'T
- Use
$1,$2,$@,$*for arguments - Use
$argsin PowerShell - Use inline
{{arg(name="x")}}syntax (deprecated, removed 2026.11) - Forget to quote glob patterns in sources
- Set env vars in
envthat deps need (they don't inherit — use structureddependswithenv) - Use
raw = trueunless interactive input needed - Set
MISE_ENVinmise.toml(it determines which files to load) - Manually add executables to shims directory (
mise reshimremoves them) - Use
MISE_RAW=1without knowing it setsMISE_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
#MISE description="Run database migrations"
#MISE alias="migrate"
#MISE depends=["db:check"]
#MISE tools={postgresql="16"}
#USAGE arg "<direction>" choices "up" "down" help="Migration direction"
#USAGE flag "-n --count <n>" default="1" help="Number of migrations"
#USAGE flag "--dry-run" help="Preview SQL only"
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"
More from aussiegingersnap/cursor-skills
api-rest
REST API conventions for Next.js App Router with Zod validation and standardized error handling. This skill should be used when creating API routes, implementing CRUD operations, or establishing API patterns for a project.
12ui-design-system
Complete design system with principles + living style guide. Enforces precise, crafted UI inspired by Linear, Notion, and Stripe. Includes boilerplate style-guide page template for Next.js/React projects. Use when building any UI that needs Jony Ive-level precision.
10tools-repo-review
Comprehensive GitHub repository analysis for engineering managers with contribution stats, code quality review, team health metrics, and actionable management outputs
9auth-better-auth
Better Auth integration for Next.js 16 with Drizzle adapter. This skill should be used when connecting to a Better Auth instance, configuring OAuth providers, or implementing protected routes with proxy.ts.
8ui-principles
Enforce a precise, minimal design system inspired by Linear, Notion, and Stripe. Use this skill when building dashboards, admin interfaces, or any UI that needs Jony Ive-level precision - clean, modern, minimalist with taste. Every pixel matters.
8ui-shadcn-studio
shadcn/studio component library with MCP integration, theme generation, and block patterns. This skill should be used when building UI with shadcn components, selecting dashboard layouts, or generating landing pages. Canonical source for all shadcn-based work.
7