mise : le couteau suisse de l'environnement de développement

mise (prononcé "meez") est un outil de gestion d'environnements de développement écrit en Rust. Il réunit en un seul fichier ce que vous faisiez avant avec asdf, direnv, et un Makefile : versions d'outils, variables d'environnement, tâches automatisées, et alias shell.
Le problème que mise résout
Vous rejoignez un projet. Le README dit d'installer Node 18, Terraform 1.5 et Python 3.11. Votre collègue a Node 20, Terraform 1.9 et Python 3.12. Un troisième a tout installé via Homebrew et n'a aucune idée de ses versions.
Le pipeline CI échoue avec une erreur obscure. Après investigation : une incompatibilité de syntaxe entre votre version de Terraform et celle du CI. Deux heures de perdues.
Le Makefile du projet contient vingt cibles, mais la moitié ne fonctionne qu'avec certains outils installés globalement. Le .env n'est pas documenté. Les variables d'environnement sont éparpillées entre .bashrc, des exports manuels, et une wiki que personne ne lit.
Ce scénario est la norme dans la plupart des équipes de développement. mise le résout en un seul fichier : mise.toml.
Qu'est-ce que mise ?
mise est le successeur spirituel d'asdf, le gestionnaire de versions multi-langages très populaire dans l'écosystème DevOps. Là où asdf se contentait de gérer les versions d'outils, mise va beaucoup plus loin :
| Ce que vous faisiez avant | Avec mise |
|---|---|
| asdf pour les versions d'outils | ✅ intégré |
| direnv pour les variables d'environnement | ✅ intégré |
| Makefile pour les tâches | ✅ intégré |
.env pour la config locale |
✅ intégré |
Alias dans .zshrc |
✅ intégré |
La philosophie est simple : le mise.toml est la source de vérité de l'environnement de développement, versionnée dans le repo, partagée par toute l'équipe.
Installation et premier pas
L'installation se fait en une ligne :
curl https://mise.run | sh
Puis on active mise dans son shell (.bashrc ou .zshrc) :
echo 'eval "$(mise activate bash)"' >> ~/.bashrc
# ou pour zsh :
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
Pour déclarer les outils d'un projet :
mise use node@22 python@3.13 terraform@1.11
Cela génère (ou met à jour) un fichier mise.toml dans le répertoire courant :
[tools]
node = "22"
python = "3.13"
terraform = "1.11"
Un simple mise install installe toutes les versions déclarées. Et mise active automatiquement les bonnes versions dès que vous entrez dans le répertoire — sans rien faire de plus.
Onboarder en 30 secondes
Voici ce qui se passe quand quelqu'un clone un projet qui utilise mise :
git clone git@gitlab.com:mon-projet.git
cd mon-projet
mise install # installe tous les outils dans leurs versions exactes
mise run # liste toutes les tâches disponibles
Cette dernière commande affiche quelque chose comme :
$ mise run
deploy Déploie l'infrastructure complète
destroy Détruit l'infrastructure
tests Lance tous les tests
docs Génère la documentation
ssh Se connecte en SSH à la workstation
Le mise.toml est aussi un README interactif. Le nouvel arrivant sait immédiatement ce qu'il peut faire, sans chercher dans une documentation qui date de 2022.
mise trust : la sécurité dès l'onboarding
Quand mise rencontre un nouveau mise.toml, il ne l'exécute pas aveuglément — il demande d'abord une confirmation explicite :
mise WARN ~/projets/mon-projet/mise.toml is not trusted.
Run `mise trust` to trust this directory.
C'est un mécanisme de sécurité : un mise.toml peut définir des hooks et des variables d'environnement qui s'exécutent automatiquement. Faire confiance implicitement à tout fichier récupéré depuis git serait risqué.
mise trust # fait confiance au répertoire courant
mise trust ~/projets/ # fait confiance à tous les projets dans ce dossier
Pour les projets de confiance permanents (vos propres repos), on peut ajouter un chemin global dans la config :
# ~/.config/mise/config.toml
[settings]
trusted_config_paths = ["~/projets"]
Le lockfile : reproductibilité garantie
Quand mise.toml déclare node = "22", cela installe la dernière 22.x.x disponible au moment de l'exécution — ce qui peut changer d'un mois à l'autre.
Pour garantir que tout le monde — et la CI — installe exactement la même version, mise peut générer un fichier mise.lock, avec la commande mise lock :
# @generated - this file is auto-generated by `mise lock`
[[tools.opentofu]]
version = "1.11.4"
backend = "aqua:opentofu/opentofu"
[tools.opentofu."platforms.linux-x64"]
checksum = "sha256:0d744081951095c3e54fd4f0af5c48491ec03116ab02f1ad5ca4ed60d3b60efd"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.4/tofu_1.11.4_linux_amd64.tar.gz"
[tools.opentofu."platforms.macos-arm64"]
checksum = "sha256:2e52b9baccf925a1516ae850112b6eddce35d96e9b59fa954d191d6e8ef3af5f"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.4/tofu_1.11.4_darwin_arm64.tar.gz"
Ce n'est pas juste une version épinglée — c'est une URL exacte + un checksum SHA256 par plateforme. Toute altération du binaire entre sa publication et son installation serait détectée. Certains outils vont encore plus loin avec un champ provenance :
[[tools.trivy]]
version = "0.69.3"
backend = "aqua:aquasecurity/trivy"
[tools.trivy."platforms.linux-x64"]
checksum = "sha256:1816b632dfe529869c740c0913e36bd1629cb7688bd5634f4a858c1d57c88b75"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.69.3/trivy_0.69.3_Linux-64bit.tar.gz"
provenance = "cosign"
[[tools.uv]]
version = "0.9.26"
backend = "aqua:astral-sh/uv"
[tools.uv."platforms.linux-x64"]
checksum = "sha256:708b752876aeeb753257e1d55470569789e465684c1d3bc1760db26360b6c28b"
url = "https://github.com/astral-sh/uv/releases/download/0.9.26/uv-x86_64-unknown-linux-musl.tar.gz"
provenance = "github-attestations"
provenance = "cosign" signifie que mise vérifie la signature Cosign du binaire. provenance = "github-attestations" vérifie une attestation GitHub Actions qui prouve que le binaire a été produit par le pipeline CI officiel du projet — et non par un acteur tiers.
C'est l'équivalent de package-lock.json ou Pipfile.lock, mais pour vos outils système, avec des garanties cryptographiques que les gestionnaires de paquets classiques n'offrent pas. Une fois mise.lock commité, mise install est déterministe et vérifiable : même résultat aujourd'hui, dans six mois, sur n'importe quelle machine.
Configuration globale : les outils du quotidien
Certains outils ne sont pas spécifiques à un projet — ils doivent être disponibles partout : jq, fzf, gh, bat, ripgrep...
Plutôt que de les installer via Homebrew ou votre gestionnaire de paquets système, mise propose une configuration globale dans ~/.config/mise/config.toml :
# ~/.config/mise/config.toml
[tools]
jq = "latest"
fzf = "latest"
gh = "latest"
bat = "latest"
ripgrep = "latest"
Ces outils sont disponibles dans tous vos terminaux, indépendamment des projets. Et avec mise upgrade, ils se mettent à jour en une commande.
La distinction est claire : global = outils transversaux, local = outils projet. mise ls vous montre à tout moment ce qui est actif et d'où ça vient.
Les tâches : le vrai différenciateur face à asdf
C'est ici que mise dépasse largement asdf. Un fichier mise.toml peut déclarer des tâches directement exécutables via mise run <tâche> — l'équivalent d'un Makefile, mais avec des fonctionnalités modernes : descriptions, dépendances, répertoire de travail, outputs.
Exemple générique :
[tasks.lint]
description = "Vérifie le style du code Python"
run = "ruff check ."
[tasks.test]
description = "Lance les tests unitaires"
depends = ["lint"] # lint s'exécute d'abord
run = "pytest tests/"
[tasks.ci]
description = "Pipeline complète : lint + tests"
depends = ["test"]
Exemple réel — chaîne de déploiement complète :
# mise.toml d'une plateforme de formation cloud
[tasks.deploy]
description = "Déploie l'infrastructure complète"
run = [
{ task = "terraform:deploy" },
{ task = "slides:build" },
{ task = "ansible:deploy" },
]
Une seule commande mise run deploy enchaîne : provisioning de l'infrastructure AWS avec OpenTofu, génération des supports de cours, et déploiement Ansible sur les machines. Chaque sous-tâche déclare son propre répertoire de travail et ses dépendances — plus de cd ci/terraform && tofu apply dans des scripts fragiles.
[tasks."terraform:deploy"]
alias = "terraform:apply"
description = "Applique les changements Terraform"
dir = "ci/terraform"
depends = ["terraform:init"]
run = ["tofu apply -auto-approve"]
Exécution parallèle et arguments
Plusieurs tâches peuvent s'exécuter en parallèle en les passant sur la même ligne :
mise run lint test build # lint, test et build tournent simultanément
Pour passer des arguments bruts à une tâche :
mise run build -- --release # args passés à build
mise run build -- --release ::: test -- --verbose # args séparés par tâche
Arguments typés avec usage
Pour aller plus loin, le champ usage permet de déclarer des arguments et des flags avec types, valeurs par défaut, choix possibles et aide auto-générée — comme une vraie CLI :
[tasks.deploy]
description = "Déploie l'application"
usage = '''
arg "<environment>" help="Environnement cible" {
choices "dev" "staging" "prod"
}
flag "-v --verbose" help="Mode verbeux"
flag "--region <region>" help="Région AWS" default="eu-west-1" env="AWS_REGION"
'''
run = '''
echo "Déploiement sur \({usage_environment?} (\){usage_region?})"
[[ "${usage_verbose?}" == "true" ]] && set -x
./deploy.sh "\({usage_environment?}" "\){usage_region?}"
'''
Les arguments deviennent automatiquement des variables d'environnement préfixées usage_ — pas de parsing manuel. Et mise génère un --help complet :
$ mise run deploy --help
Déploie l'application
Usage: deploy <environment> [OPTIONS]
Arguments:
<environment> Environnement cible [possible values: dev, staging, prod]
Options:
-v, --verbose Mode verbeux
--region <region> Région AWS [env: AWS_REGION] [default: eu-west-1]
-h, --help Print help
C'est la différence entre une tâche jetable et une tâche qui peut être utilisée par toute l'équipe sans lire son code source.
Mode watch
mise watch relance automatiquement une tâche quand ses fichiers sources changent — idéal pour le développement actif :
mise watch build # rebuild dès qu'un fichier source est modifié
Combiné avec la déclaration sources dans la tâche, mise sait exactement quels fichiers surveiller :
[tasks.build]
run = "cargo build"
sources = ["src/**/*.rs", "Cargo.toml"]
outputs = ["target/debug/myapp"]
Cerise sur le gâteau : si outputs est plus récent que sources, la tâche est ignorée automatiquement — comportement similaire à Make, sans la syntaxe archaïque.
Tâches en Python ou Node.js
Les tâches ne sont pas limitées au shell. N'importe quel interpréteur peut être utilisé via un shebang :
[tools]
python = "3.13"
[tasks.migrate]
description = "Exécute les migrations de base de données"
run = '''
#!/usr/bin/env python
import subprocess
result = subprocess.run(["python", "manage.py", "migrate"])
print("Migrations terminées !")
'''
mise utilise l'interpréteur déclaré dans [tools] — la tâche Python s'exécute avec la version de Python que mise gère, pas celle du système.
Générer la documentation des tâches
Puisque chaque tâche porte une description, mise peut en générer automatiquement une documentation Markdown :
mise gen task-docs
Le résultat est un tableau avec le nom, la description, les dépendances et les sources de chaque tâche — prêt à intégrer dans un wiki ou un README. Plus besoin de maintenir manuellement la liste des commandes disponibles : elle se dérive directement du mise.toml.
Variables d'environnement et multi-environnements
Fini le .env copié-collé entre les devs. Les variables d'environnement se déclarent directement dans mise.toml :
[env]
ANSIBLE_HOST_KEY_CHECKING = "false"
DAY = "{{ exec(command='date +%d') }}" # valeur dynamique !
MONTH = "{{ exec(command='date +%m') }}"
YEAR = "{{ exec(command='date +%Y') }}"
La syntaxe exec() permet des variables dynamiques calculées à l'exécution. Ici, DAY, MONTH et YEAR sont recalculés à chaque ouverture de terminal — pratique pour générer des noms de ressources cloud datés.
Charger un fichier .env existant
Si vous avez déjà un .env, mise peut l'inclure directement sans migration :
[env]
_.file = ".env"
DATABASE_URL = { required = true } # déclarée dans .env, vérifiée par mise
La syntaxe _.file charge le fichier .env avant d'appliquer les autres variables — ce qui permet de combiner les deux approches pendant une migration progressive.
Variables requises
mise peut marquer certaines variables comme obligatoires. Si la variable n'est pas définie, mise refuse de s'exécuter et affiche un message d'erreur explicite — plus de silences étranges quand quelqu'un oublie de configurer une clé d'API :
[env]
DATABASE_URL = { required = true }
API_KEY = { required = true }
Encore mieux : vous pouvez intégrer un message d'aide dans l'erreur pour guider le développeur :
[env]
DATABASE_URL = {
required = "Définissez DATABASE_URL avec votre chaîne de connexion PostgreSQL (ex: postgres://user:pass@localhost/dbname)"
}
AWS_ACCESS_KEY_ID = {
required = "Voir le wiki interne : Configuration des credentials AWS pour le développement local"
}
Le pattern habituel est de déclarer ces variables comme required dans mise.toml (commité), et de les définir dans mise.local.toml (ignoré par git) sur chaque poste développeur. C'est l'équivalent du .env.example + .env, mais avec validation intégrée et messages d'erreur utiles.
Multi-environnements
mise supporte nativement plusieurs fichiers d'environnement qui se surchargent :
mise.toml— base commune à toute l'équipemise.development.toml— outils et config spécifiques au dev localmise.production.toml— surcharges pour la CI/CD
# mise.production.toml — même tâche, output JUnit pour GitLab CI
[tasks."terraform:tflint"]
run = ["tflint --init", "tflint --format junit | tee tflint.junit.xml"]
On sélectionne l'environnement avec la variable MISE_ENV :
MISE_ENV=production mise run terraform:tflint
En CI, le pipeline définit simplement MISE_ENV: production — les tâches s'adaptent automatiquement. La parité local/CI est totale : les développeurs et le pipeline exécutent les mêmes commandes, avec les mêmes outils, aux mêmes versions.
Gestion des secrets
Variables d'environnement et secrets, c'est presque la même chose — sauf qu'un secret ne doit pas traîner en clair dans un repo git. mise documente plusieurs approches pour ça, avec des niveaux de maturité différents.
fnox (recommandé)
fnox est le compagnon naturel de mise pour les secrets — pas étonnant, c'est le même auteur (@jdx). Ce n'est pas une intégration directe : fnox fonctionne de manière indépendante, avec son propre fichier fnox.toml, et se charge de rendre les secrets disponibles comme variables d'environnement.
Le principe : fnox.toml vit dans le repo git, mais les secrets y sont soit chiffrés (le chiffré est committé, la clé ne l'est pas), soit des références vers un gestionnaire externe (1Password, AWS Secrets Manager, Vault, etc.) :
# fnox.toml
[providers]
age = { type = "age", recipients = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"] }
[secrets]
DATABASE_URL = { provider = "age", value = "YWdlLWVuY3J5cHRpb24uLi4=" } # chiffré, safe à committer
API_KEY = { default = "dev-key-12345" } # valeur en clair pour le dev local uniquement
L'intégration shell se configure une fois dans le profil :
eval "$(fnox activate bash)" # ou zsh, fish
Dès lors, entrer dans un répertoire avec un fnox.toml charge automatiquement les secrets comme variables d'environnement — exactement le même modèle que mise avec mise.toml. Les deux s'utilisent côte à côte sans friction.
fnox supporte une large gamme de providers : age, AWS KMS/Secrets Manager, Azure Key Vault, GCP KMS/Secret Manager, 1Password, Bitwarden, Infisical, HashiCorp Vault, et même le trousseau OS.
Les approches expérimentales de mise
Pour les cas plus simples, mise propose deux options directement dans mise.toml, toutes deux encore marquées expérimentales :
- sops — chiffre un fichier entier, chargé ensuite via
_.file - age — chiffre des variables individuelles inline dans
[env]
Ces options sont pratiques pour des projets sans gestionnaire de secrets dédié, mais restez prudents : elles sont encore jeunes et l'interface peut évoluer.
Alias shell : partiellement remplacer .zshrc
Une fonctionnalité peu connue : mise peut gérer des alias shell directement dans mise.toml, via la section [shell_alias].
# ~/.config/mise/config.toml — alias globaux
[shell_alias]
k = "kubectl"
tf = "terraform"
ll = "ls -la"
# mise.toml — alias scoped au projet
[shell_alias]
tfa = "tofu apply -auto-approve"
tfi = "tofu init"
tfp = "tofu plan"
tma = "terramate script run apply"
tmg = "terramate generate"
tml = "terramate script run lint"
tmp = "terramate script run plan"
L'avantage décisif sur les alias dans .zshrc : ils sont scoped au répertoire du projet. tfa n'existe que quand vous êtes dans ce projet. Plus de conflits entre les alias de différents projets, et les alias font partie du repo — un nouveau dev les récupère automatiquement.
Note : les
shell_aliasnécessitentexperimental = truedans[settings]de votremise.toml.
Hooks : automatiser ce qu'on oublie
Les hooks s'exécutent automatiquement quand vous entrez dans un répertoire géré par mise :
# mise.development.toml
[hooks]
enter = '''
pre-commit install
uv sync --active
'''
Résultat : quand un développeur clone le projet et fait cd mon-projet, les hooks git pre-commit sont installés et les dépendances Python synchronisées — sans qu'il ait eu à lire quoi que ce soit. Les oublis d'initialisation n'existent plus.
Note : les
hooksnécessitentexperimental = truedans[settings]de votremise.toml.
Mise à jour des outils et compatibilité Renovate
Mettre à jour les outils est trivial :
mise outdated # liste les outils avec des mises à jour disponibles
mise upgrade # installe les versions plus récentes (sans changer mise.toml)
mise upgrade --bump # met à jour ET bumpe la contrainte dans mise.toml
mise upgrade node # met à jour un outil spécifique
La nuance entre upgrade et upgrade --bump est importante : upgrade seul installe une version plus récente localement mais laisse mise.toml intact — les autres développeurs ne bénéficient pas de la mise à jour. --bump met aussi à jour mise.toml, ce qui propage le changement à l'équipe via git.
Renovation automatique avec Renovate
Renovate comprend nativement le format mise.toml. Avec une configuration minimale, il ouvre automatiquement des merge requests quand une nouvelle version d'un outil est disponible :
{
"extends": ["config:recommended"],
"packageRules": [
{
"matchManagers": ["mise"],
"automerge": true
}
]
}
Combiné avec Renovate, mise.toml devient un inventaire d'outils qui se maintient quasiment tout seul : Renovate détecte les nouvelles versions, ouvre une MR, les tests CI valident, et la MR est mergée automatiquement si tout passe.
L'écosystème : backends, plugins, et limites
Un backend est le mécanisme par lequel mise télécharge et installe un outil : il détermine la source du binaire, le format d'installation, et les vérifications de sécurité appliquées. Chaque outil dans
mise.tomlest servi par un backend —aqua,cargo,npm,ubi, etc.
Le registre officiel de mise couvre un peu plus de 1000 outils, avec un fort accent DevOps (héritage direct d'asdf) : terraform, kubectl, helm, aws-cli, k9s, kind, kustomize, helmfile...
Petit bémol : la couverture des outils plus orientés "développement" (frameworks spécifiques, outils de niche) est moins bonne. asdf dispose parfois de plugins communautaires que mise n'a pas encore intégrés. Ça s'améliore vite, mais c'est un point à vérifier avant de choisir mise sur un projet avec une toolchain inhabituelle.
Le backend aqua : sécurité intégrée
Aqua est le backend recommandé pour la grande majorité des outils CLI. Il se distingue fondamentalement des plugins asdf par son modèle de sécurité :
| Aspect | Plugins asdf | Backend aqua |
|---|---|---|
| Format | Scripts shell | YAML déclaratif |
| Exécution de code arbitraire | Oui | Non |
| Vérification des checksums | Rare | Systématique |
| Signatures cryptographiques | Non | Cosign, SLSA, minisign |
| Maintenance | Fragmentée (1 repo/plugin) | Centralisée |
Concrètement, le niveau de vérification dépend de ce que le projet publie. Le fichier mise.lock le rend explicite via le champ provenance :
- Pas de
provenance→ vérification du checksum SHA256 uniquement (ex:opentofu,tflint) provenance = "cosign"→ checksum + signature Cosign vérifiée (ex:trivy)provenance = "github-attestations"→ checksum + attestation GitHub Actions (ex:uv)
La plupart des projets publient au minimum des checksums — c'est déjà un sacré progrès par rapport à curl | sh ou à un plugin asdf qui télécharge sans rien vérifier.
Il y a quand même un point noir au tableau : aqua possède son propre registre de plus de 2200 outils, mais mise n'en intègre qu'une partie dans son binaire. Autrement dit, ce n'est pas parce qu'un outil existe chez aqua qu'on peut l'installer directement depuis mise — il faut qu'il ait été explicitement référencé. En pratique, le registre de mise tourne autour du millier d'outils, donc les outils courants du monde DevOps sont bien couverts, mais on ne peut pas exploiter l'étendue du registre aqua.
Pour voir exactement ce que votre version de mise expose via aqua :
mise doctor 2>&1 | grep "baked in"
# aqua:
# baked in registry tools: 2201 # à l'heure de cet article
Pour les outils absents, les autres backends viennent à la rescousse :
[tools]
"ubi:cli/cli" = "latest" # binaire depuis les GitHub Releases
"cargo:ripgrep" = "14" # depuis crates.io
"go:golangci-lint" = "1.64" # depuis go modules
"npm:prettier" = "latest" # depuis npm
"pypi:httpie" = "latest" # depuis PyPI
Le backend ubi est particulièrement pratique : il installe n'importe quel binaire publié dans les GitHub Releases d'un repo. Attention cependant — sans vérification cryptographique, contrairement à aqua. C'est un bon filet de sécurité pour les outils qui ne sont pas encore dans le registre de mise, mais ça ne remplace pas les garanties qu'aqua apporte.
Autres points forts de l'écosystème :
- Compatibilité asdf : les plugins asdf existants fonctionnent dans mise, facilitant la migration
- PATH plutôt que shims : mise est nettement plus rapide qu'asdf sur les temps de démarrage shell
- Intégrations IDE : VS Code, IntelliJ, Zed détectent automatiquement les environments mise
Comparaison : mise vs asdf vs devbox vs devcontainer
| Critère | mise | asdf | devbox | devcontainer |
|---|---|---|---|---|
| Gestion versions d'outils | ✅ | ✅ | ✅ | ✅ |
| Task runner intégré | ✅ | ❌ | ❌ | ❌ |
| Variables d'environnement | ✅ | ❌ | partiel | via Dockerfile |
| Config globale | ✅ | ✅ | ✅ | ❌ |
| Multi-environnements | ✅ | ❌ | ❌ | par image |
| Alias shell scoped | ✅ | ❌ | ❌ | ❌ |
| Lockfile | ✅ | ❌ | ✅ | par image |
| Compatibilité Renovate | ✅ | ❌ | partiel | ❌ |
| Isolation complète (container) | ❌ | ❌ | ✅ | ✅ |
| Vitesse d'installation | ⚡ Rust | Lent (bash) | Lent (nix) | Long (image) |
| Courbe d'apprentissage | Faible | Faible | Nix requis | Docker requis |
Quand choisir quoi :
- mise → le cas général. Projet d'équipe avec toolchain hétérogène, besoin d'un task runner et d'environnements reproductibles. C'est le point de départ par défaut.
- asdf → si vous avez un écosystème asdf déjà en place et aucun besoin de tâches ou de variables d'environnement. La migration vers mise est douce : les fichiers
.tool-versionssont compatibles. - devbox → si vous voulez une isolation Nix à 100%, avec des environnements parfaitement reproductibles au niveau des dépendances système. Courbe d'apprentissage plus élevée.
- devcontainer → si l'isolation container complète est requise (postes Windows, politique de sécurité stricte, environnements hautement hétérogènes).
Ces outils ne s'excluent pas forcément : il est courant d'utiliser mise pour les outils et les tâches, avec un devcontainer pour les développeurs sur Windows. Et pour passer de l'un à l'autre, mise a une commande toute faite :
mise gen devcontainer
Elle génère un devcontainer.json à partir du mise.toml existant — les outils déclarés dans [tools] sont automatiquement reportés dans la configuration du container. C'est une bonne façon d'offrir les deux options en parallèle sans maintenir deux configurations distinctes à la main.
Diagnostics
En cas de comportement inattendu, mise doctor est la première commande à lancer :
mise doctor
# version: 2026.1.7 linux-x64
# activated: yes
# shims_on_path: no
# ...
# ✓ No problems found
Elle vérifie l'installation, l'activation du shell, la présence de conflits, et liste les backends disponibles. Utile aussi pour s'assurer que l'intégration IDE est bien détectée.
Conclusion
mise.toml est une déclaration d'intention : voici les outils, leurs versions, comment lancer le projet, et quelle config d'environnement est nécessaire. C'est la documentation exécutable que les README ont toujours voulu être.
Pour adopter mise sur un projet existant, pas besoin de tout migrer d'un coup. Commencez par un outil :
mise use node@22
Le fichier mise.toml est créé, vous et vos collègues avez la même version de Node. Ajoutez une tâche la semaine suivante. Puis les variables d'environnement. La migration est progressive, et chaque étape apporte de la valeur immédiatement.
La documentation officielle est disponible sur mise.jdx.dev. Le registre des outils supportés : mise.jdx.dev/registry.

