Introduction à mise, le gestionnaire de versions multilangage
Voyez comment mise gère les versions de Node et Python par projet, les fichiers de version existants, le verrouillage des outils, les variables d’environnement et les builds locaux et CI.
mise est un outil en ligne de commande unique qui installe et bascule les versions de Node, Python, Ruby et d’autres runtimes par répertoire. Il lit ces versions dans un fichier mise.toml situé à la racine du projet.
Si votre dépôt contient un frontend Vite et un script Python qui génère du contenu avant le build, vous utilisez sans doute nvm et pyenv en parallèle, en espérant que le shell de chaque membre de l’équipe soit en phase avec la CI. En général, l’un d’eux ne l’est pas.
Pour une comparaison de mise, nvm, pyenv, rustup et SDKMAN!, consultez 5 Version Managers Every Developer Should Know. Cet article ne dresse pas de liste de fonctionnalités. Il prend un dépôt et le suit à travers plusieurs situations : le cd, les fichiers .nvmrc existants, le premier clone d’un collègue, la CI, une tâche de build sur deux runtimes et les variables d’environnement.
Points clés
- Avec l’activation dans le shell, entrer dans un répertoire contenant un
mise.tomlplace dans le PATH les runtimes épinglés du projet. En sortir rétablit les versions précédentes. - mise ignore
.nvmrcet.python-version, sauf si vous les activez outil par outil avec le paramètreidiomatic_version_file_enable_tools. mise runcharge lui-même les outils et l’environnement du projet, et installe par défaut les outils manquants. Il fonctionne donc en CI sans activation du shell.jdx/mise-action@v4installe mise et les outils déclarés dansmise.toml. Si unmise.lockest commité, l’installation se fait avec--locked.- La table
[env]est du texte en clair commité dans le dépôt. Elle sert à la configuration, pas aux secrets.
Le projet : un frontend Vite avec une étape de build en Python
Le dépôt d’exemple, docs-preview, comporte deux runtimes, un fichier de configuration et un workflow :
docs-preview/
├── content/*.md
├── scripts/build_content.py
├── src/
├── package.json # vite in devDependencies
├── mise.toml
└── .github/workflows/build.yml
Le script Python n’utilise que la bibliothèque standard. Il convertit les fichiers Markdown en JSON, que le frontend importe :
# scripts/build_content.py
import json, os, pathlib
src = pathlib.Path(os.environ.get("CONTENT_DIR", "content"))
out = pathlib.Path("src/generated/content.json")
out.parent.mkdir(parents=True, exist_ok=True)
items = [{"slug": p.stem, "body": p.read_text(encoding="utf-8")}
for p in sorted(src.glob("*.md"))]
out.write_text(json.dumps(items, indent=2), encoding="utf-8")
print(f"wrote {len(items)} items to {out}")
Voici le mise.toml complet. Les sections suivantes y font référence :
[tools]
node = "24"
python = "3.14"
[settings]
lockfile = true
[env]
CONTENT_DIR = "content"
VITE_SITE_NAME = "Docs Preview"
[tasks.install]
description = "Install JS dependencies"
run = "npm ci"
[tasks."build:content"]
description = "Convert content files to JSON for the frontend"
run = "python scripts/build_content.py"
[tasks.build]
description = "Generate content, then build the Vite app"
depends = ["install", "build:content"]
run = "npx vite build"
La table [tools] utilise des préfixes de version (Node 24 LTS, Python 3.14). Le lockfile, présenté plus loin, enregistre les versions de correctif exactes auxquelles ces préfixes sont résolus.
Ce qui se passe quand vous entrez dans le répertoire et en sortez
Une fois mise activé, entrer dans un répertoire contenant un mise.toml place dans votre PATH les runtimes épinglés du projet. En sortir rétablit les versions actives auparavant. Dès que mise activate figure dans le fichier de démarrage de votre shell, mise bascule les outils et les variables d’environnement à chaque changement de répertoire.
cd ~
node --version # whatever your system or nvm provides
cd ~/code/docs-preview
node --version # v24.x from mise.toml
python3 --version # Python 3.14.x
echo "$CONTENT_DIR" # content
Le moment où mise bascule les versions dépend du shell. D’après la documentation sur les shims, bash, zsh, fish et xonsh basculent dès l’exécution de cd. Les autres shells attendent l’affichage du prompt suivant.
Quand une version épinglée n’est pas encore installée
Sur une machine neuve, exécutez mise install dans le répertoire du projet. C’est la solution explicite et prévisible. Les tâches s’en chargent aussi : les tâches mise s’exécutent avec les outils et les variables d’environnement du projet. De plus, le paramètre auto_install, activé par défaut, installe les outils configurés manquants lorsque vous appelez mise run. Python demande de la vigilance si vous vous reposez sur les shims. La référence des paramètres précise qu’un shim incapable de résoudre une version gérée par mise (par exemple lorsque l’auto-installation est désactivée) se rabat sur le premier programme du même nom présent ailleurs dans le PATH. Pour un outil également fourni par l’OS, comme python3, votre version épinglée ne s’exécute alors jamais, et vous n’obtenez aucune erreur.
Pour épingler une autre version dans un seul terminal, utilisez mise shell node@<version>. Cette commande nécessite un shell dans lequel mise est déjà activé.
Fichiers .nvmrc et .python-version existants
mise ne lit pas .nvmrc ni .python-version, sauf si vous l’activez pour chaque outil avec idiomatic_version_file_enable_tools. La FAQ de mise confirme que ces fichiers de version idiomatiques sont désactivés par défaut. Ce comportement par défaut a été introduit dans mise 2025.10.0. Pour les activer :
[settings]
idiomatic_version_file_enable_tools = ["node", "python"]
La documentation de configuration cite package.json parmi les fichiers que mise lit pour node. Activer node peut donc aussi prendre ce fichier en compte. Pour ignorer un fichier précis, ajoutez une paire outil:fichier, par exemple node:package.json, au paramètre idiomatic_version_file_disable_files.
Une fois que mise.toml épingle les deux runtimes, ne conservez .nvmrc que pour les collègues qui utilisent encore nvm, et veillez à ce que les deux fichiers concordent. Pour un rappel sur la façon dont nvm traite ce fichier, consultez les guides sur le changement de version de Node avec nvm sous macOS, Linux et Windows.
Collègues et CI
Un poste de développement et un runner de CI lisent le même mise.toml, mais placent les outils dans le PATH de manières différentes :
| Poste de développement | GitHub Actions | |
|---|---|---|
| Outils dans le PATH | Hook d’activation dans le shell | jdx/mise-action installe mise et les outils épinglés |
| Source des versions | mise.toml + mise.lock | Les mêmes fichiers |
| Commande de build | mise run build | mise run build |
Le premier clone d’un collègue :
- Installer mise :
curl https://mise.run | sh - Ajouter
eval "$(~/.local/bin/mise activate zsh)"(ou la ligne correspondant à votre shell) au fichier rc de votre shell. - Relire
mise.toml, puis exécutermise install. - Exécuter
mise run build.
Le modèle de confiance de mise demande de la vigilance, car les fichiers de configuration peuvent exécuter du code. Selon le guide de démarrage, en dehors de la CI et du mode paranoïaque, toute commande qui agit sur le projet, comme mise install, mise exec ou mise run, accorde automatiquement sa confiance à la configuration active. Relisez donc mise.toml avant d’en exécuter une, et utilisez mise trust lorsque vous voulez accorder votre confiance explicitement à une configuration.
Verrouillez les versions exactes. Le lockfile, mise.lock, est créé par mise lock ou par le paramètre lockfile = true vu plus haut. Commitez-le. Avec mise install --locked, une entrée manquante dans le lockfile provoque une erreur, si bien que mise ne choisit jamais une nouvelle version à votre insu.
Workflow de CI :
# .github/workflows/build.yml
name: build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
- run: mise run build
L’étape mise-action installe mise et les outils déclarés dans mise.toml. Le workflow utilise ainsi les mêmes versions que les développeurs en local. Par défaut, elle exécute mise install (install: true) et met les outils en cache (cache: true). Lorsque mise.lock est présent, l’installation se fait avec --locked. Elle transmet aussi automatiquement ${{ github.token }}. Sur les postes de développement, définir GITHUB_TOKEN ou MISE_GITHUB_TOKEN aide lorsque les installations se heurtent aux limites de débit, comme l’explique la page sur les tokens GitHub.
En cas de problème, trois commandes permettent de cerner la cause :
| Symptôme | Commande |
|---|---|
| L’activation ou l’installation semble incorrecte | mise doctor |
| Le mauvais fichier de configuration semble s’appliquer | mise config ls |
| La mauvaise version est sélectionnée | mise ls --current |
Une vraie tâche : mise run build sur deux runtimes
Une tâche définie dans mise.toml s’exécute avec les outils épinglés et les variables [env] du projet déjà appliqués. mise run build utilise donc les mêmes versions de Node et de Python sur un poste de développement et en CI, même sans activation du shell.
La clé depends fait attendre build jusqu’à ce que toutes les tâches listées soient terminées. L’étape Python a ainsi écrit src/generated/content.json avant que Vite ne le lise. Les tâches listées peuvent en revanche s’exécuter simultanément. La documentation des tâches indique que les prérequis peuvent tourner en parallèle et que leur ordre dans depends n’établit aucune séquence. Ce n’est pas un problème ici : npm ci écrit node_modules et le script Python écrit src/generated, donc aucune des deux étapes ne touche à la sortie de l’autre. Si une étape vient un jour à consommer la sortie de l’autre, faites-la dépendre directement de cette étape.
mise tasks # lists install, build:content, build
mise run build # npm ci + Python step, then vite build
Le guide d’exécution des tâches fixe la limite par défaut à huit jobs en parallèle.
Variables d’environnement par projet avec mise
Les valeurs de la table [env] sont du texte en clair dans un fichier commité. Les variables d’environnement de mise relèvent de la gestion de configuration, pas de la gestion des secrets. Dans l’exemple, le script Python lit CONTENT_DIR via os.environ, et le frontend lit import.meta.env.VITE_SITE_NAME.
Le préfixe VITE_ rend tangible le risque lié aux valeurs [env] en clair. La documentation de Vite sur les variables d’environnement explique que toute variable commençant par VITE_ se retrouve dans le bundle client, sa valeur étant inscrite dans le code au moment du build. Toute valeur VITE_ placée dans mise.toml devient donc publique dès la mise en ligne du site.
Une variable manquante au moment du build ne fait pas échouer celui-ci. Vous obtenez un bundle qui appelle la mauvaise URL. Le session replay permet de le constater du point de vue de l’utilisateur : vous voyez les requêtes partir vers une URL de base undefined, puis vous remontez jusqu’à l’environnement dans lequel le build a été exécuté.
Quand mise vaut-il la peine ?
Si un projet n’a besoin que de Node, nvm et un .nvmrc font déjà l’affaire, et mise reste facultatif. Les guides nvm couvrent bien cette configuration. mise vaut la peine d’être adopté lorsqu’un même dépôt épingle au moins deux runtimes et que la CI doit correspondre à chaque poste de développement. Pour l’essayer sur un dépôt existant, ajoutez un mise.toml avec des versions épinglées dans [tools], exécutez mise lock, commitez les deux fichiers, puis remplacez l’étape de build de votre CI par mise run build.
FAQ
Où conserver les secrets si mise.toml est commité ?
Conservez les secrets dans un fichier mise.local.toml ignoré par git, ou déclarez-les dans mise.toml avec required = true : mise vérifie alors que la variable est définie sans en stocker la valeur. Ajouter redact = true masque les valeurs dans la sortie capturée des tâches, mais mise env les affiche toujours en clair. Pour les secrets qui doivent être commités, mise peut déchiffrer des fichiers SOPS chiffrés avec age (une fonctionnalité expérimentale) pour mise exec, les tâches et l'activation du shell.
mise lit-il les fichiers .tool-versions d'asdf ?
Oui. Contrairement à .nvmrc, mise lit .tool-versions sans aucun paramètre supplémentaire. Sous Unix, il peut aussi exécuter les plugins shell d'asdf, sans garantie toutefois que chaque commande ou plugin asdf fonctionne. Si mise.toml et .tool-versions déclarent le même outil dans le même répertoire, mise.toml l'emporte. La documentation de mise déconseille de partager les répertoires d'installation entre asdf et mise : exécutez donc mise install après la migration.
Pourquoi mon éditeur ou mon script utilise-t-il une autre version de Node que mon terminal ?
Les éditeurs, les hooks git et les planificateurs de tâches ne chargent souvent pas votre fichier rc interactif, si bien que le hook d'activation de mise ne s'exécute jamais. Pour y remédier, ajoutez mise activate zsh --shims (ou la ligne correspondant à votre shell) à un profil de connexion lu par votre éditeur, comme ~/.zprofile, et conservez le simple mise activate dans ~/.zshrc. Pour les scripts, utilisez plutôt mise exec -- commande ou mise run. Le mode shims fait l'impasse sur certaines fonctionnalités de l'activation, comme la plupart des hooks.