Mise development environment manager (asdf + direnv + make replacement)...
Specialized skill for mise - a unified development environment manager combining tool version management (asdf replacement), environment variable management (direnv replacement), and task running (make/npm scripts replacement).
mise uses backends to install tools. Backend selection affects security verification, performance, and compatibility.
| Backend | Syntax | Use For |
|---|---|---|
| core | node, python, go |
Built-in tools (node, python, bun, deno, java, go, erlang, dotnet). Rust-native, best performance. |
| aqua | aqua:owner/repo |
Tools in aqua-registry. Native security verification (cosign, SLSA, attestations, minisign). |
| github | github:owner/repo |
GitHub releases. Provenance verification, download progress. Replaced ubi. |
Tier 2 (Stable)
| Backend | Syntax | Use For |
|---|---|---|
| cargo | cargo:crate |
Rust tools from crates.io. Supports cargo-binstall. |
| npm | npm:package |
Node packages. Supports npm/pnpm/bun/aube as package managers. |
| pipx | pipx:package |
Python CLI tools in isolated envs. Auto-uses uvx if uv is on PATH. |
| go | go:module |
Go tools via go install. |
| gem | gem:package |
Ruby gems. |
| conda | conda:package |
Conda packages. Graduated from experimental in v2026.5. |
| vfox | vfox:plugin |
VersionFox plugins. Embedded Lua in binary for speed. |
| http | http:url |
Direct HTTP downloads with Tera templating. |
| forgejo | forgejo:owner/repo |
Forgejo/Gitea forge releases. |
| gitlab | gitlab:owner/repo |
GitLab releases. |
| asdf | asdf:plugin |
Legacy plugin system. Discouraged for new tools — runs arbitrary plugin code. |
Deprecated
| Backend | Replacement | Migration |
|---|---|---|
| ubi | github | Replace ubi:owner/repo → github:owner/repo. github backend adds provenance verification, progress reports, fewer deps. |
Resolution order: Explicit spec → MISE_BACKENDS_<TOOL> env var → Registry lookup → Core tools → Fallback.
Recommendation hierarchy: core > aqua > github > language-native (npm/pipx/cargo/go/gem) > vfox > asdf
Backend override example:
[tools]
# Default (registry decides backend — usually aqua)
uv = "latest"
# Explicit backend
"aqua:astral-sh/uv" = "latest"
"github:astral-sh/uv" = "latest"
# CLI override
mise use "github:astral-sh/uv@latest"
The aqua backend verifies tool integrity via native Rust implementations — no external CLI tools (cosign, slsa-verifier, minisign, gh) needed. All methods enabled by default.
| Method | Env Var | Settings Key | Default |
|---|---|---|---|
| Cosign signatures | MISE_AQUA_COSIGN |
aqua.cosign |
true |
| SLSA provenance | MISE_AQUA_SLSA |
aqua.slsa |
true |
| GitHub Attestations | MISE_AQUA_GITHUB_ATTESTATIONS |
aqua.github_attestations |
true |
| Minisign | MISE_AQUA_MINISIGN |
aqua.minisign |
true |
| Checksums | Always on | N/A | Always |
Global toggle across all backends: MISE_GITHUB_ATTESTATIONS=0
Extra cosign args: MISE_AQUA_COSIGN_EXTRA_ARGS="--key /path/to/key.pub"
When Attestation Verification Fails
Common causes: release published manually without GH Actions (no attestations generated), sigstore library incompatibility, GitHub API format changes.
# Fix 1: Update mise first (many attestation bugs fixed in newer releases)
mise self-update
# Fix 2: Disable only the failing method
export MISE_AQUA_GITHUB_ATTESTATIONS=false
mise install <tool>@<version>
# Fix 3: Settings-based (persistent)
# In mise.toml or ~/.config/mise/config.toml
[settings]
aqua.github_attestations = false
# Fix 4: Debug to identify which method fails
MISE_DEBUG=1 mise install <tool>@<version>
Known per-tool attestation issues:
Skip mise for:
ruby = { file = ".ruby-version" } java = { file = ".java-version" }
postgres = "16" redis = "7"
**Global Development Tools**
```bash
# Install globally useful CLI tools
mise use -g ripgrep@latest # Better grep
mise use -g bat@latest # Better cat
Version File Migration
# Migrate from existing version files
echo "20.10.0" > .node-version
echo "3.11.6" > .python-version
# mise.toml
[tools]
node = { file = ".node-version" }
python = { file = ".python-version" }
[env] PROJECT_ROOT = "{{cwd}}" LOG_LEVEL = "debug"
[vars] project_name = "my-app"
[tasks.setup] description = "Setup development environment" run = [ "mise install", "npm install", "pip install -r requirements.txt", "cp .env.example .env" ]
[tasks.dev] alias = "d" description = "Start development server" depends = ["setup"] env = { NODE_ENV = "development" } run = "npm run dev"
**Monorepo Configuration**
```toml
# Root mise.toml
[tools]
node = "20"
go = "1.21"
[tasks.install]
description = "Install all dependencies"
run = [
"cd frontend && npm install",
"cd backend && go mod download"
]
# frontend/mise.toml
[tasks.dev]
dir = "{{cwd}}/frontend"
run = "npm run dev"
# backend/mise.toml
[tools]
go = "1.21"
[tasks.dev]
dir = "{{cwd}}/backend"
run = "go run main.go"
[tasks.dev-watch] description = "Watch and rebuild on changes" run = "mise watch build"
**Build Pipeline with Caching**
```toml
[tasks.clean]
description = "Remove build artifacts"
run = "rm -rf dist"
[tasks.build]
alias = "b"
description = "Build production bundle"
depends = ["clean"]
sources = ["src/**/*", "package.json", "tsconfig.json"]
outputs = ["dist/**/*"]
env = { NODE_ENV = "production" }
run = "npm run build"
[tasks.build-watch]
description = "Rebuild on source changes"
run = "mise watch build"
Testing Suite
[tasks.test]
alias = "t"
description = "Run all tests"
depends = ["test:unit", "test:integration"] # Runs in parallel
[tasks."test:unit"]
description = "Run unit tests"
sources = ["src/**/*.ts", "tests/unit/**/*.ts"]
run = "npm test -- --testPathPattern=unit"
[tasks."test:integration"]
description = "Run integration tests"
sources = ["src/**/*.ts", "tests/integration/**/*.ts"]
run = "npm test -- --testPathPattern=integration"
[tasks."test:watch"]
description = "Run tests in watch mode"
run = "npm test -- --watch"
[tasks."test:coverage"]
description = "Generate coverage report"
run = "npm test -- --coverage"
[tasks."test:e2e"]
description = "Run end-to-end tests"
depends = ["build"]
run = "playwright test"
Database Workflow
[tasks."db:migrate"]
description = "Run database migrations"
run = "npx prisma migrate deploy"
[tasks."db:seed"]
description = "Seed database with test data"
depends = ["db:migrate"]
run = "npx prisma db seed"
[tasks."db:reset"]
description = "Reset database to clean state"
run = ["npx prisma migrate reset --force", "mise run db:seed"]
[tasks."db:studio"]
description = "Open Prisma Studio"
run = "npx prisma studio"
Linting & Formatting
[tasks.lint]
description = "Lint code"
sources = ["src/**/*.ts"]
run = "eslint src"
[tasks.format]
description = "Format code"
sources = ["src/**/*.ts"]
run = "prettier --write src"
[tasks."lint:fix"]
description = "Lint and auto-fix issues"
run = "eslint src --fix"
[tasks.check]
description = "Run all checks"
depends = ["lint", "format", "test"] # Runs in parallel
Deployment Pipeline
[tasks.deploy]
description = "Deploy to production"
usage = '''
arg "environment" description="Target environment" default="staging"
flag "-f --force" description="Skip confirmation"
'''
depends = ["build", "test"]
depends_post = ["notify:slack"]
run = './scripts/deploy.sh {{arg(name="environment")}} {{flag(name="force")}}'
[tasks."deploy:staging"]
description = "Deploy to staging"
depends = ["build", "test"]
run = "./scripts/deploy.sh staging"
[tasks."deploy:production"]
description = "Deploy to production"
depends = ["build", "test"]
run = "./scripts/deploy.sh production"
[tasks."notify:slack"]
hide = true
run = 'curl -X POST $SLACK_WEBHOOK -d "Deployment complete"'
Docker Integration
[tasks."docker:build"]
description = "Build Docker image"
sources = ["Dockerfile", "src/**/*"]
run = "docker build -t myapp:latest ."
[tasks."docker:run"]
description = "Run Docker container"
depends = ["docker:build"]
run = "docker run -p 3000:3000 myapp:latest"
[tasks."docker:compose"]
description = "Start services with docker-compose"
run = "docker-compose up -d"
Go Plugin Build System
[tasks."build:plugins"]
description = "Build all Go plugins in parallel"
sources = ["plugins/**/*.go"]
outputs = ["plugins/**/main.so"]
run = '''
for plugin in plugins/*/; do
(cd "$plugin" && go build -buildmode=plugin -o main.so main.go) &
done
wait
'''
[tasks."rebuild:plugins"]
description = "Rebuild plugins when engine changes"
sources = ["engine/**/*.go"]
depends = ["build:engine"]
run = "mise run build:plugins"
_.file = ".env"
[env]
NODE_ENV = "development" LOG_LEVEL = "debug"
API_URL = "{{vars.api_url}}" DATABASE_URL = "postgres://{{vars.db_host}}:{{vars.db_port}}/myapp" DEBUG = "{{vars.debug_mode}}"
[tasks.dev] env = { NODE_ENV = "development", API_URL = "{{vars.api_url}}" } run = "npm run dev"
**Multi-Environment Setup**
```toml
# mise.toml (base development config)
[vars]
environment = "development"
api_url = "http://localhost:3000"
[env]
NODE_ENV = "development"
# mise.staging.toml
[vars]
environment = "staging"
api_url = "https://api.staging.example.com"
[env]
NODE_ENV = "staging"
# mise.production.toml
[vars]
environment = "production"
api_url = "https://api.example.com"
debug_mode = "false"
[env]
NODE_ENV = "production"
Secret Management
# mise.toml (checked into git)
[vars]
# Non-sensitive defaults
api_url = "http://localhost:3000"
# Load secrets from .env (gitignored)
_.file = ".env"
[env]
# Reference secrets loaded from .env
API_KEY = "{{vars.api_key}}"
DATABASE_PASSWORD = "{{vars.db_password}}"
# .env (NOT in git)
api_key=secret-key-here
db_password=secret-password
Assess Current State
Design Architecture
Implement Configuration
Optimize Performance
jobs limitValidate and Test
mise install to verify tool installationmise tasks ls to verify task registrationmise run <task>mise doctor for diagnostics.tool-versions:
nodejs 20.10.0
python 3.11.6
golang 1.21.5
terraform 1.6.6
mise.toml:
[tools]
node = "20.10.0"
python = "3.11.6"
go = "1.21.5"
terraform = "1.6.6"
Migration command:
# Mise can read .tool-versions directly
mise install
# Or convert to mise.toml
mise use node@20.10.0 python@3.11.6 go@1.21.5 terraform@1.6.6
Makefile:
.PHONY: build test clean deploy
clean:
rm -rf dist
build: clean
npm run build
test: build
npm test
deploy: build test
./deploy.sh
mise.toml:
[tasks.clean]
description = "Remove build artifacts"
run = "rm -rf dist"
[tasks.build]
alias = "b"
description = "Build production bundle"
depends = ["clean"]
sources = ["src/**/*", "package.json"]
outputs = ["dist/**/*"]
run = "npm run build"
[tasks.test]
alias = "t"
description = "Run tests"
depends = ["build"]
run = "npm test"
[tasks.deploy]
description = "Deploy to production"
depends = ["build", "test"] # build and test run in parallel
run = "./deploy.sh"
Advantages:
package.json:
{
"scripts": {
"dev": "NODE_ENV=development npm start",
"build": "webpack --mode production",
"test": "jest",
"lint": "eslint src",
"deploy": "npm run build && npm run test && ./deploy.sh"
}
}
mise.toml:
[tasks.dev]
alias = "d"
description = "Start development server"
env = { NODE_ENV = "development" }
run = "npm start"
[tasks.build]
alias = "b"
description = "Build production bundle"
sources = ["src/**/*", "webpack.config.js"]
outputs = ["dist/**/*"]
run = "webpack --mode production"
[tasks.test]
alias = "t"
description = "Run tests"
run = "jest"
[tasks.lint]
description = "Lint code"
sources = ["src/**/*.js"]
run = "eslint src"
[tasks.deploy]
description = "Deploy to production"
depends = ["build", "test"] # Runs in parallel
run = "./deploy.sh"
Advantages:
.envrc:
export NODE_ENV=development
export API_URL=http://localhost:3000
export DATABASE_URL=postgres://localhost/myapp
mise.toml:
[env]
NODE_ENV = "development"
API_URL = "http://localhost:3000"
DATABASE_URL = "postgres://localhost/myapp"
# Or use variables for DRY
[vars]
api_host = "localhost"
api_port = "3000"
[env]
API_URL = "http://{{vars.api_host}}:{{vars.api_port}}"
Advantages:
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Setup mise
uses: jdx/mise-action@v2
with:
version: latest # or specific version
- name: Install tools and dependencies
run: mise install
- name: Run tests
run: mise run test
- name: Build
run: mise run build
**GitLab CI**
```yaml
image: ubuntu:latest
before_script:
- curl https://mise.run | sh
- export PATH="$HOME/.local/bin:$PATH"
- mise install
test:
script:
- mise run test
build:
script:
- mise run build
Docker
FROM ubuntu:latest
# Install mise
RUN curl https://mise.run | sh
ENV PATH="/root/.local/bin:$PATH"
# Copy project files
COPY . /app
WORKDIR /app
# Install tools and dependencies
RUN mise install
# Run build
RUN mise run build
CMD ["mise", "run", "start"]
Task Not Found
# Symptom: "Task 'xyz' not found"
mise tasks ls # List all tasks
mise config # Show active config files
cat mise.toml # Verify task definition
mise tasks info <task> # Get task details
Task Caching Issues
# Symptom: Task not re-running when files change
[tasks.build]
sources = ["src/**/*"] # Check glob patterns are correct
outputs = ["dist/**/*"] # Verify output paths match actual outputs
run = "npm run build"
# Debug: Remove outputs and re-run
# rm -rf dist && mise run build
Environment Variables Not Loading
# Symptom: Environment variables not set in tasks
mise config # Verify mise.toml location (project root)
mise run --verbose <task> # Check env loading with verbose output
mise doctor # Diagnostic check
env | grep VAR_NAME # Check if var is actually set
Cross-Platform Issues
# Symptom: Task fails on Windows
[tasks.build]
run = "npm run build" # Use cross-platform commands
run_windows = "npm.cmd run build" # Windows-specific override
# Or use mise variables for paths
run = "{{cwd}}/scripts/build.sh"
Parallel Execution Not Working
# Symptom: Tasks running sequentially instead of parallel
[tasks.ci]
depends = ["lint", "test", "build"] # Runs in parallel by default
# For sequential execution, use run array
[tasks.sequential]
run = [
"mise run step1",
"mise run step2",
"mise run step3"
]
Tool Installation Fails
# Symptom: mise install fails for a tool
mise doctor # Check for system dependencies
mise ls-remote node # List available versions
mise install node@20 --verbose # Verbose installation
mise cache clear # Clear cache and retry
Attestation / Verification Failures
# Symptom: "GitHub artifact attestations verification failed"
# or "Workflow verification failed: expected '...', found certificate: None"
# Step 1: Update mise (most attestation bugs are fixed in newer releases)
mise self-update
# Step 2: If still failing, disable the specific verification method
export MISE_AQUA_GITHUB_ATTESTATIONS=false # GitHub attestations
export MISE_AQUA_COSIGN=false # Cosign signatures
export MISE_AQUA_SLSA=false # SLSA provenance
# Step 3: Try a different version (some releases lack attestations)
mise install uv@0.9.13 # Skip known-bad versions
# Step 4: Switch backend as workaround
mise use "github:owner/repo@version" # github backend instead of aqua
# Step 5: Debug for details
MISE_DEBUG=1 mise install tool@version
Using Deprecated ubi Backend
# Symptom: ubi backend warnings or failures
# Fix: Replace ubi with github backend
# Old: ubi:owner/repo → New: github:owner/repo
# In mise.toml
# Before (deprecated):
# "ubi:goreleaser/goreleaser" = "latest"
# After (recommended):
# "github:goreleaser/goreleaser" = "latest"
Task Configuration:
Environment Management:
Performance:
Cross-Platform:
Team & CI:
mise doctorWhen creating mise configurations:
mise run commandsmise install when setting up toolsResponse:
# mise.toml
[tools]
node = "20.10.0"
[env]
NODE_ENV = "development"
[tasks.install]
description = "Install dependencies"
run = "npm install"
[tasks.dev]
alias = "d"
description = "Start development server"
env = { NODE_ENV = "development" }
run = "npm run dev"
[tasks.build]
alias = "b"
description = "Build for production"
sources = ["src/**/*", "package.json"]
outputs = ["dist/**/*"]
env = { NODE_ENV = "production" }
run = "npm run build"
[tasks.test]
alias = "t"
description = "Run tests"
run = "npm test"
Setup:
mise install # Install Node.js 20.10.0
mise run install # Install npm dependencies
mise dev # Start development server
Response:
# mise.toml
[tools]
node = "20.10.0"
python = "3.11.6"
[env]
PROJECT_ROOT = "{{cwd}}"
[tasks."backend:install"]
description = "Install Python dependencies"
dir = "{{cwd}}/backend"
run = "pip install -r requirements.txt"
[tasks."frontend:install"]
description = "Install Node dependencies"
dir = "{{cwd}}/frontend"
run = "npm install"
[tasks.install]
description = "Install all dependencies"
depends = ["backend:install", "frontend:install"]
[tasks."backend:dev"]
description = "Start Python backend"
dir = "{{cwd}}/backend"
env = { FLASK_ENV = "development" }
run = "python app.py"
[tasks."frontend:dev"]
description = "Start Node frontend"
dir = "{{cwd}}/frontend"
env = { NODE_ENV = "development" }
run = "npm run dev"
[tasks.dev]
description = "Start both frontend and backend"
depends = ["backend:dev", "frontend:dev"]
Usage:
mise install # Install both Node and Python
mise run install # Install all dependencies
mise dev # Start both services in parallel
Do:
mise doctor before committinggithub: over ubi: for GitHub release toolsmise self-update before debugging attestation failures