# 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 :

```bash
curl https://mise.run | sh
```

Puis on active mise dans son shell (`.bashrc` ou `.zshrc`) :

```bash
echo 'eval "$(mise activate bash)"' >> ~/.bashrc
# ou pour zsh :
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
```

Pour déclarer les outils d'un projet :

```bash
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 :

```toml
[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 :

```bash
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é.

```bash
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 :

```toml
# ~/.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` :

```toml
# @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` :

```toml
[[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` :

```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 :**

```toml
[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 :**

```toml
# 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.

```toml
[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 :

```bash
mise run lint test build   # lint, test et build tournent simultanément
```

Pour passer des arguments bruts à une tâche :

```bash
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 :

```toml
[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 :

```bash
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 :

```toml
[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 :

```toml
[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 :

```bash
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` :

```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 :

```toml
[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 :

```toml
[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 :

```toml
[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'équipe
- `mise.development.toml` — outils et config spécifiques au dev local
- `mise.production.toml` — surcharges pour la CI/CD

```toml
# 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` :

```bash
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.) :

```toml
# 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 :

```bash
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]`.

```toml
# ~/.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_alias` nécessitent `experimental = true` dans `[settings]` de votre `mise.toml`.

---

## Hooks : automatiser ce qu'on oublie

Les hooks s'exécutent automatiquement quand vous entrez dans un répertoire géré par mise :

```toml
# 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 `hooks` nécessitent `experimental = true` dans `[settings]` de votre `mise.toml`.

---

## Mise à jour des outils et compatibilité Renovate

Mettre à jour les outils est trivial :

```bash
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 :

```json
{
  "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.toml` est 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 :

```bash
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 :

```toml
[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-versions` sont 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 :

```bash
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 :

```bash
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 :

```bash
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](https://mise.jdx.dev). Le registre des outils supportés : [mise.jdx.dev/registry](https://mise.jdx.dev/registry.html).*
