Use this skill when working with mise to manage your project. All projects should rely on mise for package management, encapsulating common tasks, and consolidating devops operations.
mise.tomlmise.toml then copy the base to the project root as mise.tomlWhen you see a relevant match to your current task, STOP! Read no further and load the applicable reference.
Are you starting a fresh project? See starting-fresh
Are you integrating mise in a brownfield project? See brownfield
Were you asked to encapsulate a multi-step custom workflow? See custom-workflows
Did you create a new script, add a new CLI command, or get asked to expose or make available any of the former as a convenience task? See wraping-an-interface
Are you implementing or adapting one of the supported common workflows (Database, Build, CI, Test, Deploy, Lint)? See common-workflows
Then, define tasks directly in mise.toml under the [tasks.*] section:
[tasks.build]
description = "Build the project"
run = "cargo build"
[tasks.test]
description = "Run tests"
run = "cargo test"
depends = ["build"]
Execute: mise run build or mise build
Implement the task as an executable shell or python script in .mise/tasks/ directory:
#!/usr/bin/env bash
#MISE description="Build the project"
#MISE depends=["lint"]
cargo build
Place in .mise/tasks/build (no extension), make executable, and run identically: mise run build
project-root/
āāā mise.toml # Primary config with [tasks.*] section
āāā .mise/tasks/ # Directory for file-based tasks
ā āāā build # Executable task script
ā āāā test # Executable task script
ā āāā deploy # Executable task script
[tasks.task-name]
description = "Task description shown in mise tasks"
run = "command to execute"
depends = ["other-task"]
env = { VAR = "value" }
dir = "{{ config_root }}"
sources = ["src/**/*.rs"]
outputs = ["target/release/binary"]
Use #MISE comments for task configuration:
#!/usr/bin/env bash
#MISE description="Deploy application"
#MISE depends=["build", "test"]
#MISE sources=["dist/**/*"]
#MISE env={ENVIRONMENT="production"}
# Task implementation
./deploy.sh
Essential Fields:
run (TOML tasks only, required)
run = "cargo build"run = ["cargo build", "cargo test"]run = [{ task = "lint" }, "cargo build"]description
mise tasks listingdepends
depends = ["lint", "test"]depends_post
depends_post = ["cleanup"]env
env = { NODE_ENV = "production", API_KEY = "secret" }tools
tools = ["node@20", "python@3.12"]dir
"{{ config_root }}" (where mise.toml lives)dir = "{{ cwd }}/subdir"shell
shell = "bash -c"sources
sources = ["src/**/*.rs", "Cargo.toml"]outputs
outputs = [{ auto = true }]outputs = ["target/release/binary"]Caching behavior:
mise run --force to bypass cachehide
mise tasks output, help, and completionshide = truequiet
quiet = truesilent
true (both), "stdout", "stderr"silent = "stdout"raw
raw = trueconfirm
confirm = "Are you sure you want to deploy?"Define formal arguments and flags in usage field:
[tasks.deploy]
run = "deploy.sh"
usage = """
{usage} [OPTIONS] <environment>
Arguments:
<environment> Target environment [env: ENVIRONMENT]
Options:
--force Skip confirmation
"""
mise run task-name # Full command
mise r task-name # Short alias
mise task-name # Shorthand (avoid in scripts)
Extra arguments pass through to the task:
mise run build --release
mise run test -- --nocapture
Run sequentially:
mise run lint build test
Run separate sequences with ::: delimiter:
mise run build arg1 ::: test arg2
Default: 4 parallel jobs. Control via:
--jobs N flagMISE_JOBS environment variablejobs setting in mise.tomlmise run -j 8 task1 task2 task3
Output is line-prefixed to prevent interleaving. Use --interleave for direct stdout/stderr.
mise tasks # List all tasks
mise tasks --hidden # Include hidden tasks
mise tasks deps [tasks]... # Show task dependencies
mise watch task-name # Re-run on file changes
Uses watchexec internally to monitor source files.
[tasks.ci]
description = "Run CI checks"
depends = ["lint", "test", "build"]
[tasks.deploy]
description = "Deploy application"
depends = ["ci"]
depends_post = ["notify"]
run = "./deploy.sh"
[tasks.build]
description = "Build for development"
run = "npm run build"
env = { NODE_ENV = "development" }
[tasks."build:prod"]
description = "Build for production"
run = "npm run build"
env = { NODE_ENV = "production" }
[tasks.compile]
description = "Compile only if sources changed"
run = "gcc src/*.c -o bin/app"
sources = ["src/*.c", "src/*.h"]
outputs = ["bin/app"]
#!/usr/bin/env bash
#MISE description="Full CI pipeline"
#MISE depends=["lint", "test"]
#MISE sources=["src/**/*"]
set -euo pipefail
echo "Running build..."
cargo build --release
echo "Running integration tests..."
cargo test --release
[tasks.backend]
description = "Start backend server"
dir = "{{ config_root }}/backend"
run = "cargo run"
[tasks.frontend]
description = "Start frontend dev server"
dir = "{{ config_root }}/frontend"
run = "npm run dev"
[tasks.dev]
description = "Start full development environment"
depends = ["backend", "frontend"]
MISE_ORIGINAL_CWD - Initial working directoryMISE_CONFIG_ROOT - Directory containing mise.tomlMISE_PROJECT_ROOT - Project root directoryMISE_TASK_NAME - Current task identifierMISE_TASK_DIR - Task script location (file tasks)MISE_TASK_FILE - Full task script path (file tasks)# 1. Create mise.toml
`cp ./references/base-mise.toml mise.toml`
# 2. Trust the config
mise trust
# 3. Verify tasks
mise tasks
For projects with Makefiles, migrate to mise for better dependency management:
# Instead of Makefile targets
[tasks.install]
description = "Install dependencies"
run = "npm install"
[tasks.build]
description = "Build project"
depends = ["install"]
sources = ["src/**/*"]
outputs = ["dist/"]
run = "npm run build"
[tasks.test]
description = "Run tests"
depends = ["build"]
run = "npm test"
Benefits over Make:
# 1. Create task directory
mkdir -p .mise/tasks
# 2. Create executable script
cat > .mise/tasks/deploy <<'BASH'
#!/usr/bin/env bash
#MISE description="Deploy application to production"
#MISE depends=["test"]
#MISE confirm="Deploy to production?"
#MISE env={ENVIRONMENT="production"}
set -euo pipefail
echo "Deploying to production..."
$MISE_PROJECT_ROOT/scripts/deploy.sh "$@"
BASH
# 3. Make executable
chmod +x .mise/tasks/deploy
# 4. Run it
mise run deploy
build, test, deploytest:unit, test:integration, test:e2emise run test:* runs all test tasksdepends for prerequisites: depends = ["lint", "test"]depends_post for cleanup: depends_post = ["notify"]sources for input filesoutputs for generated artifactssources = ["src/**/*.rs"]{ auto = true } for automatic output detectionUse File Tasks when:
Use TOML Tasks when:
In TOML tasks:
[tasks.robust]
run = ["set -euo pipefail", "./script.sh"]
In File tasks:
#!/usr/bin/env bash
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Task implementation
Check:
Syntax errors in mise.toml: mise tasks --verbose
Missing description field
Task marked hide = true
Config not trusted: mise trust
Troubleshooting: Task Not Caching
Verify:
sources and outputs are defined
Globs match files: ls src/**/*.rs
Output files exist after task runs
Use mise run --force task-name to bypass cache once
Troubleshooting: File Task Not Executable
chmod +x mise-tasks/task-name
Set explicit working directory:
[tasks.task-name]
dir = "{{ config_root }}/subdir"
run = "make build"
For interactive tasks or tasks requiring stdin:
[tasks.interactive]
raw = true
run = "npm run dev"