mise — Gestor de versiones y entornos
⚠️ Verificar versiones antes de usar — la versión de mise y los runtimes mencionados aquí pueden estar desactualizados. Consultar
mise ls-remote mise | tail -5o mise.jdx.dev para la versión más reciente. Ver politicas-core.
Qué es
En una frase: mise instala automáticamente la versión correcta de cada programa que un proyecto necesita, para que todo el equipo use exactamente lo mismo sin instalar nada a mano.
mise es un gestor de versiones políglota y runner de tareas. Reemplaza a nvm, pyenv, rbenv, asdf y Makefile/npm scripts en un solo binario escrito en Rust. Activa automáticamente las versiones correctas de cada herramienta al entrar a un directorio.
Por qué lo usamos en Wiedii
La razón central es reproducibilidad sin fricción: cada desarrollador, en cualquier máquina, ejecuta exactamente las mismas versiones de bun, node y python que el resto del equipo — sin pasos manuales, sin scripts de setup, sin documentos de "antes de empezar".
Además reemplaza tres herramientas separadas:
- nvm / pyenv / asdf → mise gestiona todos los runtimes en un solo lugar
- npm scripts / Makefile → las tasks de mise son el runner estándar
- dotenv / direnv → mise activa variables de entorno por directorio
Instalación
brew install mise
Activar en el shell (va en ~/.zprofile):
eval "$(mise activate zsh --shims)"
~/.zprofilese carga al abrir una terminal nueva (no en las ya abiertas). Después de editar este archivo, abre una terminal nueva para que tome efecto — o ejecutaexec zshen el terminal actual.
Bondades clave
Activación automática por directorio
Al entrar a un directorio con mise.toml, mise activa las versiones declaradas sin ningún comando adicional. Al salir, las desactiva.
cd ~/Docker/proyecto-alpha
bun --version # 1.2.5 — del mise.toml del proyecto
cd ~/Docker/proyecto-beta
bun --version # 1.1.8 — diferente proyecto, diferente versión
cd ~
bun --version # 1.3.14 — del config global
Esto funciona mediante shims: mise intercepta los binarios y redirige a la versión correcta según el directorio. No requiere eval en cada directorio ni hooks de cd.
mise-lock — reproducibilidad exacta entre máquinas
mise.lock fija las versiones resueltas exactas (con checksums y URLs) de todas las herramientas; se commitea al repo. Ojo: lockfile = true solo habilita que mise lea y escriba el lock — no lo crea. Hay que generarlo una vez con mise lock; después mise install/mise use/mise upgrade lo mantienen.
# ~/.config/mise/config.toml o mise.toml del proyecto
[settings]
lockfile = true # habilita el lock; el ARCHIVO se crea con `mise lock`
mise lock # crea mise.lock (una vez, al crear el repo)
mise lock --platform macos-arm64,linux-x64 # cubrir mac (dev) + linux (CI/Docker)
# mise.lock (commitear al repo)
[[tools.bun]]
version = "1.3.14"
backend = "core:bun"
Con el lockfile en git, mise install --yes en cualquier máquina instala exactamente la misma versión, sin drift entre desarrolladores. experimental no es necesario para el lockfile.
mise exec — ejecutar con versiones específicas sin activar el entorno
mise exec (o mise x) ejecuta un comando con las herramientas de mise activas, incluso desde contextos donde el entorno no está inicializado: hooks de git, scripts de CI, cron jobs.
# Ejecutar un comando con las versiones del mise.toml actual
mise exec -- bun run build
mise exec -- python script.py
# Abreviado
mise x -- taplo fmt mise.toml
mise x -- hadolint Dockerfile
# Con versión específica sin mise.toml
mise exec bun@1.2.5 -- bun test
Esto es especialmente útil en lefthook.yaml para garantizar que los hooks usen las versiones del proyecto aunque el shell no tenga el entorno activado:
# lefthook.yaml
pre-commit:
commands:
toml:
glob: '*.toml'
run: mise exec -- taplo fmt {staged_files}
hadolint:
glob: 'Dockerfile'
run: mise exec -- hadolint {staged_files}
Tasks — runner de tareas integrado
mise incluye un runner de tareas que reemplaza npm run, Makefile y scripts de shell. Las tasks se declaran en mise.toml y son auto-documentadas.
# mise.toml
[tasks.setup]
# ⚠️ Una sola cadena con `&&`, NO un array. El hook `toml` compartido formatea con
# taplo usando `reorder_arrays=true`, que reordena alfabéticamente CUALQUIER array TOML
# al hacer commit — incluido este `run` — y rompería el orden de ejecución. Ver [[wiedii-configs]].
run = "mise install --yes && mise lock && pkg=$(find . -maxdepth 2 -name 'package.json' ! -path '*/node_modules/*' | head -1) && { [ -n "$pkg" ] && bun install --cwd "$(dirname "$pkg")" || true; }"
description = "Configura el entorno completo del proyecto"
[tasks.dev]
run = "bun run dev"
description = "Arranca el servidor de desarrollo"
[tasks.test]
run = "bun test"
description = "Ejecuta los tests"
[tasks.lint]
run = "bun eslint . --cache"
description = "Lint del código fuente"
mise run setup # configuración completa con un comando
mise run dev # servidor de desarrollo
mise tasks # lista todas las tasks disponibles con descripción
⚠️ Arrays en
runvs. el hooktomlcompartido. El hooktomlde wiedii-configs formatea con taplo usandoreorder_arrays=true, que reordena alfabéticamente cualquier array TOML al hacer commit (y constage_fixedre-stagea el cambio). Para tareas multi-paso donde el orden importa —comosetup— usa una sola cadena con&&en lugar de un array: una cadena no es un array y taplo no la toca, así el orden de ejecución queda garantizado. Para arrays donde el orden es irrelevante, el array está bien.
mise trust — modelo de seguridad
mise no activa un mise.toml a menos que el desarrollador lo haya marcado explícitamente como confiable. Esto evita la ejecución automática de código malicioso al entrar en un directorio clonado.
mise trust # confiar en el mise.toml del directorio actual
mise trust --all # confiar en todos los mise.toml del sistema (⚠️ úsalo solo en máquinas personales)
El workflow estándar en Wiedii:
git clone git@gitlab.wiedii.co:<namespace>/proyecto.git
cd proyecto
mise trust # explícitamente confiar en el proyecto
mise run setup # ahora se puede ejecutar el setup
📄 Documentación: Trusted configs
Backends múltiples
mise instala herramientas desde múltiples fuentes. Antes de agregar cualquier herramienta, verificar su backend disponible en mise-versions.jdx.dev.
Core tools (runtimes del lenguaje) — node, bun, python, go, ruby, rust, deno, java, swift, zig, elixir, erlang — van con su nombre corto, sin prefijo (core: es redundante). Para el resto de herramientas (CLIs/binarios), el prefijo es obligatorio y la prioridad es:
| Prioridad | Backend | Ejemplo | Cuándo usarlo |
|---|---|---|---|
| 1º | aqua | terraform, golangci-lint | Preferido siempre. Registro curado de mise con checksums verificados. |
| 2º | npm | mise use npm:aws-cdk | CLIs publicadas en npm que no van en el package.json del proyecto. |
| 3º | pipx | mise use pipx:ruff | CLIs de Python que no van en pyproject.toml. |
| 4º | cargo | mise use cargo:taplo-cli | CLIs Rust no disponibles en aqua. |
| 5º | asdf | plugins heredados | Solo si ningún otro backend funciona. |
Regla clave: herramientas que pertenecen al ecosistema del lenguaje van en su gestor nativo (
prettier→package.json,ruff→pyproject.toml), no en mise. Excepción: CLIs de Go siempre van enmise.tomlporquego.modsolo registra librerías importadas en código, nunca executables. Ver gestion-herramientas-brew-mise para el árbol de decisión completo y la tabla de ejemplos.
📄 Catálogo de herramientas y backends 📄 Documentación: Registry 📄 Documentación: Backends
Configuración estándar de Wiedii
Config global (~/.config/mise/config.toml)
[tools]
bun = "1.3.14"
node = "24.16.0"
pnpm = "11.6.0"
python = "3.14.6"
uv = "0.11.21"
[settings]
lockfile = true
Config de proyecto (mise.toml en la raíz del repo)
[tools]
bun = "1.3.14" # versión específica del proyecto — sobreescribe global
lefthook = "2.1.9"
[settings]
lockfile = true
[hooks]
# instala lefthook tras `mise install` (no en la task de setup); se salta en CI
postinstall = "[ -z "$CI" ] && lefthook install || true"
[tasks.setup]
# ⚠️ Una sola cadena con `&&`, NO un array. El hook `toml` compartido formatea con
# taplo usando `reorder_arrays=true`, que reordena alfabéticamente CUALQUIER array TOML
# al hacer commit — incluido este `run` — y rompería el orden de ejecución. Ver [[wiedii-configs]].
run = "mise install --yes && mise lock && pkg=$(find . -maxdepth 2 -name 'package.json' ! -path '*/node_modules/*' | head -1) && { [ -n "$pkg" ] && bun install --cwd "$(dirname "$pkg")" || true; }"
description = "Configura el entorno completo del proyecto"
[env] — variables privadas para herramientas Go del registro interno
Cuando el mise.toml declara una herramienta con backend go: desde el registro interno de Wiedii (gitlab.wiedii.co/... — el caso típico es wietoo, ver wietoo-cli), el bloque [env] del propio mise.toml debe declarar GOPRIVATE cubriendo ese host:
[env]
GOPRIVATE = "gitlab.wiedii.co/*" # wiedii-registry es un grupo interno, no público
[tools]
"go:gitlab.wiedii.co/wiedii-registry/wietoo-cli/cmd/wietoo" = "vX.Y.Z"
Sin GOPRIVATE, el backend go: (que por dentro corre go install) intenta el proxy y sumdb públicos, que no pueden resolver un módulo privado, y el setup falla. Declararlo en [env] — no con un go env -w manual — hace que con solo mise trust && mise run setup la variable quede activa para ese directorio, coherente con la filosofía de mise (sin pasos manuales).
Como además el grupo es interno, cada máquina necesita una sola vez el rewrite de Git para autenticarse por SSH en vez de HTTPS anónimo (esto es config de host, no del proyecto):
git config --global url."git@gitlab.wiedii.co:".insteadOf "https://gitlab.wiedii.co/"
Si mise run setup falla bajando wietoo con un error de red o autenticación y el [env].GOPRIVATE ya está presente, casi siempre falta este paso. Detalle completo (incluida la variante para CI) en modulos-go y wietoo-cli.
Comandos clave
# Gestión de versiones
# Para el config global, debes estar en el directorio correcto:
cd ~/.config/mise && mise install --yes # instalar runtimes globales
cd -
# Para instalar las herramientas del proyecto (desde la raíz del repo):
mise install --yes # instalar herramientas del mise.toml del proyecto
mise use bun@1.3.14 # agregar herramienta al mise.toml del proyecto
mise use --global bun@1.3.14 # agregar al config global
mise ls # listar herramientas activas en el directorio
mise ls --current # solo las herramientas activas ahora
mise outdated # ver qué herramientas tienen versión más nueva
# Ejecución
mise run setup # ejecutar task 'setup'
mise tasks # listar todas las tasks disponibles
mise exec -- <comando> # ejecutar comando con el entorno de mise activo
# Config y confianza
mise trust # confiar en el mise.toml actual
mise config # ver config efectivo del directorio actual
Troubleshooting rápido
mise run setup falla con "not trusted":
mise trust && mise run setup
Herramienta no se activa al entrar al directorio:
mise ls # verificar que está declarada en mise.toml
mise trust # verificar que el directorio está en trusted
eval "$(mise activate zsh)" # verificar que la activación está en el shell
Versión incorrecta (el global sobreescribe al proyecto):
# La activación de mise debe ir al FINAL de tu config de shell para tener máxima
# prioridad. En el setup estándar de Wiedii va en ~/.zprofile (ver configuracion-zsh):
tail -3 ~/.zprofile # debe terminar con la activación de mise / los shims en el PATH
# Si moviste la línea, recarga: exec zsh (en cada terminal abierta)
Conflicto con versión global:
mise ls --current # ver qué versión está activa y de dónde viene
Referencias
- Documentación oficial mise
- mise-versions.jdx.dev — catálogo de herramientas y backends
- mise-lock — lockfiles
- mise exec — ejecutar con entorno
- Tasks — runner de tareas
- Trusted configs — seguridad
- Registry de herramientas
- Backends (aqua, npm, pipx, cargo, asdf)
- Referencia completa de CLI
- gestion-herramientas-brew-mise — arquitectura de 3 niveles
- guia-nuevo-dev — onboarding paso a paso
- mise-tooling — política detallada de mise.toml