🛠️Herramientas

mise: gestiona versiones de Node.js y otras herramientas por proyecto

Felipe••14 min de lectura
Aprende a usar mise con Node.js, pnpm y mise.toml. Prueba dos proyectos con versiones diferentes y conoce sus límites, tareas y precauciones de seguridad.

Abres un proyecto que necesita Node.js 22 y después otro que utiliza Node.js 24. Ambos tienen sus dependencias instaladas, pero tu terminal sigue ejecutando la misma versión de node. El resultado puede ser un error de compatibilidad, una instalación diferente de la esperada o una prueba que funciona únicamente en tu máquina.

El problema tiene dos partes: disponer de las versiones necesarias y seleccionar la correcta al trabajar en cada proyecto. mise permite declarar herramientas y versiones en un archivo del repositorio, instalarlas y preparar el entorno de ejecución correspondiente.

Vamos a comprobarlo con dos proyectos pequeños. También veremos qué relación tiene con pnpm, cómo se integra con la terminal y qué conviene revisar antes de confiar en la configuración de un repositorio ajeno.

Qué gestiona mise y qué sigue siendo responsabilidad del proyecto

mise es un gestor de herramientas de desarrollo que también ofrece configuración de variables de entorno y ejecución de tareas. Puede administrar runtimes como Node.js y otras herramientas de línea de comandos. Su documentación de herramientas describe cómo selecciona las versiones que utiliza cada proyecto.

Un runtime es el entorno que ejecuta un programa: en nuestro caso, Node.js ejecutará JavaScript. Una dependencia como Express tiene otro papel: es una biblioteca que instalamos para utilizarla desde la aplicación.

La separación práctica es esta:

  • mise selecciona las versiones de Node.js, pnpm u otras herramientas.
  • pnpm instala las dependencias de la aplicación y ejecuta los scripts de package.json.
  • Tu código y sus pruebas determinan si la aplicación funciona con esas versiones.

Si necesitas profundizar en la segunda parte, el artículo sobre pnpm y la gestión de dependencias explica su store, node_modules y lockfile.

mise tampoco convierte el proyecto en un contenedor. El sistema operativo, las bibliotecas del sistema y los servicios externos siguen influyendo. Para levantar una base de datos y una caché locales junto a una API, podemos combinarlo con Docker Compose.

mise frente a nvm, asdf y Volta

Las cuatro herramientas pueden resolver necesidades parecidas alrededor de Node.js, pero su alcance y forma de integración cambian.

HerramientaEnfoque y selección de versiones
nvmNode.js por shell, con nvm use y .nvmrc. El cambio al entrar en carpetas puede configurarse con hooks.
asdfMúltiples herramientas mediante plugins, .tool-versions y shims.
VoltaEcosistema JavaScript, con shims y versiones fijadas en package.json mediante volta pin.
miseHerramientas, entornos y tareas mediante mise.toml e integración con la shell; también ofrece shims.

Un shim es un ejecutable intermediario que decide qué instalación debe atender una invocación. No contiene toda la herramienta: la dirige hacia la versión seleccionada.

La documentación de nvm, la guía de asdf y la explicación de Volta permiten contrastar estos comportamientos. La diferencia no consiste en que solo mise pueda cambiar versiones automáticamente.

Si únicamente trabajas con Node.js y nvm ya cubre tus necesidades, migrar no es obligatorio. mise resulta especialmente interesante cuando un repositorio necesita coordinar Node.js, el gestor de paquetes y otras herramientas sin repartir sus versiones entre varios mecanismos.

Instalar mise y conectarlo con la terminal

En macOS, si utilizas Homebrew:

brew install mise
mise --version

En Linux puedes utilizar el instalador oficial. Una forma de evitar ejecutar directamente una descarga es guardarla y revisarla primero:

curl -fsSL https://mise.run -o install-mise.sh
less install-mise.sh

# Ejecutar después de revisar el archivo y su procedencia.
sh install-mise.sh

~/.local/bin/mise --version

El instalador coloca normalmente el ejecutable en ~/.local/bin/mise. Leer el script ayuda a revisar lo que se ejecutará, pero no constituye una auditoría completa de su cadena de suministro. La guía oficial de instalación recoge otras opciones y los requisitos de cada plataforma.

Activación en Zsh y Bash

Instalar mise no basta para que node cambie automáticamente en una terminal abierta. Hay que integrar mise con la shell.

Si mise ya está en tu PATH, ejecuta en Zsh:

eval "$(mise activate zsh)"

Para mantenerlo en nuevas sesiones, añade esa misma línea una sola vez a ~/.zshrc, o al archivo correspondiente si utilizas un ZDOTDIR personalizado.

En Bash, la línea es:

eval "$(mise activate bash)"

Añádela al archivo de inicio interactivo que cargue tu Bash, normalmente ~/.bashrc. En sesiones de login, comprueba que tu perfil carga ese archivo.

Si utilizaste el instalador y mise todavía no está en el PATH, sustituye mise por ~/.local/bin/mise en la línea elegida. No necesitas añadir ambas variantes ni activar dos shells distintas.

PATH es la lista de directorios donde la shell busca ejecutables. La activación ajusta el entorno para encontrar la versión adecuada al cambiar de proyecto. No cambia el runtime de un proceso que ya estaba ejecutándose: un servidor iniciado anteriormente debe reiniciarse si quieres que use otra versión. La documentación de integración con shells explica esta activación y las alternativas para procesos no interactivos.

Versión global y versión del proyecto

Puedes establecer una versión predeterminada para tu usuario:

mise use --global --pin node@24

Esto modifica tu configuración global de mise. Es opcional: no lo ejecutes si quieres conservar tu selección actual. Una configuración local puede elegir otra versión para un proyecto concreto.

Dentro de un proyecto nuevo:

mise use --path mise.toml --pin node@22

mise use instala la herramienta y escribe su selección en la configuración. --path mise.toml hace explícito el archivo que queremos modificar; --pin guarda la versión exacta resuelta. Sin fijarla, una petición como node@22 puede quedar expresada como una versión parcial. Consulta los detalles de mise use.

En cambio, al recibir un repositorio con su configuración preparada, mise install instala lo declarado. No necesitas reemplazar las versiones del equipo por tus preferencias globales.

mise combina configuraciones según su ubicación y prioridad. En el caso habitual, la elección del proyecto prevalece sobre la global para esa herramienta. Si el resultado te sorprende, revisa los archivos efectivos con mise config ls; la referencia de configuración documenta la precedencia.

Laboratorio: dos proyectos y dos versiones de Node.js

Necesitas mise instalado, conexión a Internet para descargar herramientas y la activación de tu shell. Trabaja en una carpeta nueva bajo tu control; no reutilices un repositorio desconocido para estos pasos.

1. Preparar las versiones

mkdir -p mise-lab/proyecto-a mise-lab/proyecto-b
cd mise-lab/proyecto-a

mise use --path mise.toml --pin node@22 pnpm@11.14.0

cd ../proyecto-b

mise use --path mise.toml --pin node@24 pnpm@11.14.0

Ambos proyectos comparten pnpm y utilizan versiones distintas de Node.js. No hace falta activar Corepack para esta ruta de instalación de pnpm: aquí lo instala mise. Evita gestionar el mismo ejecutable simultáneamente con varias herramientas sin revisar cuál gana en el PATH.

En la ejecución de este laboratorio, proyecto-a/mise.toml quedó así:

[tools]
node = "22.23.4"
pnpm = "11.14.0"

Y proyecto-b/mise.toml:

[tools]
node = "24.22.2"
pnpm = "11.14.0"

Esos son los valores obtenidos en la prueba, no una promesa sobre qué parche resolverá node@22 o node@24 cuando lo ejecutes. Para reproducir exactamente esas versiones, utiliza los números completos en los comandos de instalación.

2. Crear un programa que identifique el entorno

En cada carpeta, crea version.mjs con el mismo contenido:

import { basename } from 'node:path';

const project = basename(process.cwd());

console.log(`${project}: ${process.version}`);

process.cwd() devuelve el directorio de trabajo y process.version, la versión del proceso Node.js que está ejecutando el archivo.

Crea también este package.json en proyecto-a:

{
  "name": "proyecto-a",
  "private": true,
  "type": "module",
  "packageManager": "pnpm@11.14.0",
  "scripts": {
    "version": "node version.mjs"
  }
}

En proyecto-b, usa el mismo contenido cambiando únicamente name por proyecto-b. Mantén la versión de packageManager coherente con la de pnpm declarada en mise.toml.

Desde mise-lab, instala en ambos proyectos:

cd proyecto-a
pnpm install

cd ../proyecto-b
pnpm install

No necesitamos dependencias externas para observar el cambio de runtime. pnpm install prepara el proyecto y genera su lockfile.

3. Cambiar de carpeta y comprobar el resultado

Ejecuta los comandos uno a uno en tu terminal interactiva, con mise activado. Desde proyecto-b:

cd ../proyecto-a
node --version
pnpm --version
pnpm run version

cd ../proyecto-b
node --version
pnpm run version

cd ../proyecto-a
node --version

Las líneas relevantes observadas en la prueba fueron:

# En proyecto-a
v22.23.4
11.14.0
proyecto-a: v22.23.4

# En proyecto-b
v24.22.2
proyecto-b: v24.22.2

# De vuelta en proyecto-a
v22.23.4

El cambio A → B → A se comprobó en una sesión interactiva de Zsh con mise 2026.11.2. No ejecutamos nvm use, no reinstalamos Node.js al cambiar de carpeta y no modificamos package.json entre comprobaciones.

Para diagnosticar una selección inesperada:

mise config ls
mise ls --current
mise which node
command -v node
node --version

Si mise which node y command -v node apuntan a instalaciones diferentes, revisa la activación y otros gestores que estén modificando el PATH. mise doctor puede ayudar a detectar problemas de configuración.

4. Ejecutar sin depender de una terminal interactiva

Los scripts y procesos de CI no tienen por qué cargar tu .zshrc. Para utilizar las herramientas del proyecto de forma explícita:

mise exec -- node --version
mise exec -- pnpm run version

Desde el directorio mise-lab también puedes seleccionar la carpeta:

mise exec --cd proyecto-a -- pnpm run version
mise exec --cd proyecto-b -- pnpm run version

mise exec prepara el entorno del comando. Esto evita depender del comportamiento de una sesión interactiva, aunque sigue siendo necesario instalar mise en el entorno donde se ejecute.

Añadir una herramienta y una tarea sin duplicar responsabilidades

En proyecto-b, podemos incorporar jq para consultar el package.json:

mise use --path mise.toml --pin jq@1.8

mise exec -- jq --version
mise exec -- jq '.scripts' package.json

En la prueba se instaló jq 1.8.2 y la consulta devolvió el script version. El registro de herramientas de mise permite consultar qué instala cada nombre y mediante qué backend. Un backend es el mecanismo que mise utiliza para obtener e instalar una herramienta; no todas proceden del mismo distribuidor.

Para aprender más operaciones sobre archivos estructurados, puedes continuar con jq y yq desde la terminal.

mise también tiene un ejecutor de tareas. Añade a proyecto-a/mise.toml, después de [tools] y sus versiones:

[tasks.version]
description = "Mostrar el proyecto y su versión de Node.js"
run = "pnpm run version"

Y ejecuta desde ese proyecto:

mise run version

Esta tarea delega en el script de pnpm; no introduce una segunda implementación del programa. La documentación de tareas describe cómo combinar comandos y dependencias entre tareas.

En una aplicación Node.js pequeña, pnpm run puede ser suficiente. Las tareas de mise aportan más cuando necesitas coordinar herramientas distintas o pasos compartidos por varios componentes. Declarar una tarea no significa que se ejecute automáticamente al entrar en la carpeta.

Qué guardar en Git

Versiona mise.toml junto con package.json, pnpm-lock.yaml y el código. Así, una revisión puede mostrar que cambió tanto una dependencia como el runtime previsto.

Un .gitignore mínimo para estos proyectos puede contener:

node_modules/
.env
mise.local.toml

Si utilizas configuración local, evita colocar allí decisiones necesarias para todo el equipo. Tampoco guardes credenciales en el archivo compartido: las variables de entorno no sustituyen a un gestor de secretos.

Para reforzar la resolución de herramientas, mise dispone de un lockfile opcional:

mise lock
mise install --locked

mise.lock registra versiones resueltas y, según el backend y la plataforma, información de los artefactos como URL y checksum. Inclúyelo en Git cuando adoptes este flujo y revisa los requisitos de plataformas de tu equipo en la documentación de mise.lock.

Los dos lockfiles tienen responsabilidades distintas: mise.lock corresponde a las herramientas y pnpm-lock.yaml, a las dependencias del proyecto. Fijar versiones mejora la reproducibilidad, pero no demuestra que un paquete sea seguro ni reproduce por sí solo todo el sistema operativo.

Seguridad: revisar la configuración antes de ejecutarla

Un repositorio puede contener mucho más que [tools]: tareas, hooks, plantillas y scripts. Algunas funciones permiten ejecutar comandos con los permisos de tu usuario. No trates mise.toml como un documento necesariamente pasivo.

Hay un detalle importante en el comportamiento actual: en el modo normal, comandos como mise install, mise exec y mise run pueden confiar automáticamente en la configuración activa. Tampoco debes asumir que toda configuración sencilla mostrará una pregunta de confianza. La referencia de mise trust explica estos casos; revisa el repositorio antes de ejecutar comandos, no después de esperar una confirmación que quizá no aparezca.

En la práctica, conviene comprobar:

  • Qué herramientas, backends y URLs se utilizarán para descargar ejecutables.
  • Qué comandos incluyen las tareas y los scripts a los que llaman.
  • Si existen hooks, plantillas o archivos adicionales capaces de ejecutar código.
  • Qué credenciales y permisos tendrá el proceso que los ejecute.

Los hooks pueden vincular acciones a eventos del entorno, como entrar en un directorio. Ese comportamiento es distinto de seleccionar una versión de Node.js o declarar una tarea que se ejecuta manualmente.

mise ofrece un modo paranoid, que refuerza las comprobaciones de confianza y desactiva la confianza automática. Es una opción adicional para entornos donde interesa revisar cambios de configuración con mayor rigor; no convierte el código aceptado en inocuo ni reemplaza el aislamiento del sistema.

Confiar en una configuración no equivale a auditarla ni a ejecutarla en un sandbox. Evita permisos innecesarios y directorios de confianza demasiado amplios. La guía de seguridad de mise desarrolla el modelo y sus límites.

Migrar sin dejar varios gestores compitiendo

Una migración gradual resulta más fácil de comprobar que reemplazar todo el entorno de una vez:

  1. Identifica qué ejecutables utilizas hoy con command -v node, node --version y pnpm --version.
  2. Declara las mismas versiones en un proyecto de prueba y compruébalas mediante mise exec.
  3. Ejecuta instalación, pruebas y compilación del proyecto con ese entorno.
  4. Revisa tu configuración de shell y evita que dos gestores seleccionen Node.js simultáneamente.
  5. Migra los demás repositorios cuando hayas confirmado compatibilidad, incluidos terminales del editor y CI.

Si vienes de nvm, mise puede leer archivos como .nvmrc, pero el soporte de archivos de versión propios de Node.js no está habilitado por defecto en la configuración actual. Para habilitarlo explícitamente:

mise settings add idiomatic_version_file_enable_tools node

También puedes mantener mise.toml como declaración explícita. No confundas el rango engines.node de package.json con una selección automática de runtime: revisa qué archivos y campos admite la integración de Node.js.

Si vienes de asdf, mise admite .tool-versions, pero usa sus propias instalaciones. No compartas manualmente los directorios de herramientas entre ambos gestores. La guía de migración desde asdf detalla las diferencias.

Si vienes de Volta, traslada conscientemente las versiones fijadas en package.json a la configuración elegida y revisa sus shims en el PATH. No elimines instalaciones anteriores hasta comprobar que los proyectos y sus automatizaciones funcionan con el nuevo mecanismo.

Adoptarlo cuando reduzca trabajo real

mise aporta valor cuando las versiones dejan de ser una preferencia individual y pasan a ser parte del contrato del repositorio. El laboratorio muestra una ventaja concreta: entrar en dos carpetas y obtener el runtime declarado en cada una, manteniendo el mismo gestor de paquetes.

También tiene costos: aprender su configuración, mantenerla actualizada, revisar sus fuentes de instalación y coordinarla con el editor y CI. La disponibilidad de una herramienta depende de su backend, plataforma y arquitectura; compartir un archivo no elimina esas diferencias.

Si ya tienes un flujo sencillo y consistente con npm, nvm o Volta, no necesitas cambiarlo por obligación. Empieza por un proyecto donde la selección de versiones cause problemas medibles y comprueba si mise los reduce sin añadir más mantenimiento del que ahorra.

Referencias

#mise#Node.js#pnpm#mise.toml#gestión de versiones#entorno de desarrollo#nvm#asdf

Artículos relacionados