Biome : Remplacer ESLint et Prettier par un outil unique ultra-rapide

AI Bot
Par AI Bot ·

Chargement du lecteur de synthèse vocale...

Votre pipeline ESLint + Prettier prend 45 secondes ? Biome fait la même chose en moins de 2 secondes. Biome est un formateur et linter tout-en-un écrit en Rust qui remplace ESLint, Prettier et leurs dizaines de plugins. Dans ce tutoriel, vous migrerez un projet Next.js complet vers Biome et découvrirez pourquoi des milliers de projets ont fait le switch en 2026.

Ce que vous apprendrez

À la fin de ce tutoriel, vous saurez :

  • Comprendre ce que fait Biome et pourquoi il remplace ESLint + Prettier
  • Installer et configurer Biome dans un projet JavaScript/TypeScript existant
  • Migrer automatiquement vos règles ESLint et Prettier vers Biome
  • Configurer des règles de linting personnalisées par fichier et par dossier
  • Intégrer Biome dans VS Code avec le formatage automatique
  • Ajouter Biome à votre pipeline CI/CD (GitHub Actions et GitLab CI)
  • Utiliser les imports organisés et le tri automatique
  • Configurer Biome pour un monorepo avec des règles partagées

Prérequis

Avant de commencer, assurez-vous de disposer de :

  • Node.js 18+ installé (node --version)
  • Un projet JavaScript ou TypeScript existant (idéalement avec ESLint/Prettier)
  • Familiarité avec la ligne de commande
  • VS Code ou un éditeur avec support LSP
  • Connaissance basique des fichiers de configuration (JSON)

Pourquoi Biome ?

En 2026, la majorité des projets JavaScript utilisent ESLint pour le linting et Prettier pour le formatage. Cette combinaison fonctionne, mais elle a des problèmes concrets :

  • Lenteur : ESLint parse chaque fichier en JavaScript, ce qui est intrinsèquement lent sur les gros projets
  • Configuration complexe : entre .eslintrc, .prettierrc, eslint-config-*, les plugins, les parsers et les conflits ESLint/Prettier, la configuration devient un casse-tête
  • Conflits : ESLint et Prettier peuvent se contredire — il faut eslint-config-prettier pour désactiver les règles en conflit
  • Maintenance : chaque outil a son cycle de mises à jour, ses breaking changes et ses plugins à maintenir

Biome résout tout cela avec une approche différente :

AspectESLint + PrettierBiome
LangageJavaScript (lent)Rust (rapide)
Outils2 outils + plugins1 seul outil
Config2-4 fichiers1 fichier biome.json
Vitesse~45s sur 1000 fichiers~1.5s sur 1000 fichiers
ConflitsFréquentsImpossibles

Étape 1 : Installer Biome

Créons un nouveau projet pour la démonstration, ou utilisez votre projet existant :

# Créer un projet Next.js de test
npx create-next-app@latest biome-demo --typescript --tailwind --app --src-dir
cd biome-demo

Installez Biome comme dépendance de développement :

npm install --save-dev --save-exact @biomejs/biome

La version exacte est recommandée (--save-exact) car Biome suit le versionnage sémantique et les mises à jour mineures peuvent ajouter de nouvelles règles qui génèrent des erreurs dans votre CI.

Initialisez la configuration :

npx @biomejs/biome init

Cela crée un fichier biome.json à la racine du projet :

{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "vcs": {
    "enabled": false,
    "clientKind": "git",
    "useIgnoreFile": false
  },
  "files": {
    "ignoreUnknown": false,
    "ignore": []
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "tab"
  },
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  }
}

Étape 2 : Configurer le formateur

Biome utilise des tabulations par défaut, mais la plupart des projets JavaScript utilisent 2 espaces. Configurons le formateur pour correspondre aux conventions habituelles :

{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "lineEnding": "lf"
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "double",
      "semicolons": "always",
      "trailingCommas": "all",
      "arrowParentheses": "always",
      "bracketSpacing": true,
      "jsxQuoteStyle": "double"
    }
  }
}

Comparaison avec Prettier

Si vous venez de Prettier, voici la correspondance des options :

PrettierBiomeValeur par défaut
tabWidthindentWidth2
useTabsindentStyle: "tab""space"
printWidthlineWidth80
singleQuotequoteStyle: "single""double"
semisemicolons"always"
trailingCommatrailingCommas"all"
endOfLinelineEnding"lf"

Testez le formateur sur votre projet :

# Vérifier sans modifier (mode check)
npx @biomejs/biome format --write .
 
# Voir les différences sans appliquer
npx @biomejs/biome format .

Étape 3 : Configurer le linter

Le linter de Biome intègre plus de 300 règles, dont la plupart des règles populaires de eslint, typescript-eslint, eslint-plugin-react, eslint-plugin-react-hooks et eslint-plugin-jsx-a11y.

Règles recommandées

Par défaut, "recommended": true active un ensemble de règles sûres et consensuelles :

{
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  }
}

Personnaliser les règles

Vous pouvez ajuster individuellement chaque règle :

{
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "complexity": {
        "noExcessiveCognitiveComplexity": {
          "level": "warn",
          "options": {
            "maxAllowedComplexity": 20
          }
        }
      },
      "style": {
        "noNonNullAssertion": "warn",
        "useConst": "error",
        "useImportType": "error",
        "noParameterAssign": "error"
      },
      "suspicious": {
        "noExplicitAny": "warn",
        "noConsoleLog": "warn"
      },
      "correctness": {
        "noUnusedVariables": "error",
        "noUnusedImports": "error",
        "useExhaustiveDependencies": "warn"
      },
      "nursery": {
        "useSortedClasses": {
          "level": "warn",
          "options": {
            "attributes": ["className"],
            "functions": ["clsx", "cn", "cva"]
          }
        }
      }
    }
  }
}

Les règles dans la catégorie nursery sont expérimentales et peuvent changer entre les versions mineures. Utilisez-les en mode warn plutôt que error dans votre CI.

Catégories de règles

Biome organise ses règles en catégories claires :

CatégorieDescriptionExemples
correctnessErreurs probablesnoUnusedVariables, useExhaustiveDependencies
suspiciousCode suspectnoExplicitAny, noConsoleLog
styleConventions de codeuseConst, useImportType
complexityCode trop complexenoExcessiveCognitiveComplexity
performanceOptimisationsnoAccumulatingSpread, noDelete
securityVulnérabilitésnoDangerouslySetInnerHtml
a11yAccessibilitéuseAltText, useAriaProps
nurseryExpérimentalesuseSortedClasses

Lancez le linter :

# Linter seul
npx @biomejs/biome lint .
 
# Linter avec corrections automatiques
npx @biomejs/biome lint --write .
 
# Linter + formateur + imports en une commande
npx @biomejs/biome check --write .

Étape 4 : Migrer depuis ESLint et Prettier

Si vous avez un projet existant avec ESLint et Prettier, Biome fournit un outil de migration automatique.

Migration automatique

# Migrer la configuration ESLint vers Biome
npx @biomejs/biome migrate eslint --write
 
# Migrer la configuration Prettier vers Biome
npx @biomejs/biome migrate prettier --write

Cela lit vos fichiers .eslintrc.* et .prettierrc.*, puis met à jour biome.json avec les règles équivalentes.

Exemple concret

Supposons cette configuration ESLint :

// .eslintrc.json (avant)
{
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react-hooks/recommended",
    "prettier"
  ],
  "rules": {
    "@typescript-eslint/no-unused-vars": "error",
    "@typescript-eslint/no-explicit-any": "warn",
    "react-hooks/exhaustive-deps": "warn",
    "no-console": "warn"
  }
}

Après migration, Biome génère :

// biome.json (après migration)
{
  "linter": {
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedVariables": "error",
        "useExhaustiveDependencies": "warn"
      },
      "suspicious": {
        "noExplicitAny": "warn",
        "noConsoleLog": "warn"
      }
    }
  }
}

Nettoyer les anciens fichiers

Une fois la migration validée, supprimez les anciens fichiers :

# Supprimer les fichiers ESLint
rm -f .eslintrc .eslintrc.js .eslintrc.json .eslintrc.yml .eslintignore
 
# Supprimer les fichiers Prettier
rm -f .prettierrc .prettierrc.js .prettierrc.json .prettierrc.yml .prettierignore
 
# Désinstaller les dépendances
npm uninstall eslint prettier eslint-config-prettier \
  eslint-plugin-react eslint-plugin-react-hooks \
  @typescript-eslint/eslint-plugin @typescript-eslint/parser \
  eslint-config-next

Mettre à jour les scripts npm

{
  "scripts": {
    "lint": "biome check .",
    "lint:fix": "biome check --write .",
    "format": "biome format --write ."
  }
}

Étape 5 : Organisation des imports

Biome trie automatiquement vos imports selon des conventions claires. Activez cette fonctionnalité :

{
  "organizeImports": {
    "enabled": true
  }
}

Avant / Après

// Avant — imports désordonnés
import { useState, useEffect } from "react";
import axios from "axios";
import styles from "./page.module.css";
import { Button } from "@/components/ui/button";
import type { User } from "@/types";
import { z } from "zod";
import Link from "next/link";
// Après — triés automatiquement
import { useEffect, useState } from "react";
 
import Link from "next/link";
import axios from "axios";
import { z } from "zod";
 
import type { User } from "@/types";
import { Button } from "@/components/ui/button";
import styles from "./page.module.css";

Biome regroupe les imports dans cet ordre :

  1. Modules natifs Node.js (node:fs, node:path)
  2. Packages externes (react, next, zod)
  3. Imports internes (alias @/, chemins relatifs)
  4. Imports de type (type { ... })

La commande biome check --write applique le tri en même temps que le linting et le formatage.


Étape 6 : Intégration VS Code

Installer l'extension

Recherchez "Biome" dans le marketplace VS Code ou installez-la depuis le terminal :

code --install-extension biomejs.biome

Configurer VS Code

Ajoutez ces paramètres dans .vscode/settings.json :

{
  "editor.defaultFormatter": "biomejs.biome",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.organizeImports.biome": "explicit",
    "quickfix.biome": "explicit"
  },
  "[javascript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[json]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "biomejs.biome"
  }
}

Désactivez les extensions ESLint et Prettier pour éviter les conflits. Biome remplace les deux.

Fonctionnalités dans l'éditeur

Avec l'extension Biome, vous bénéficiez de :

  • Formatage au save : le code est formaté automatiquement à chaque sauvegarde
  • Diagnostics en temps réel : les erreurs de linting apparaissent directement dans l'éditeur
  • Quick fixes : Ctrl+. propose des corrections automatiques
  • Tri des imports : les imports sont réorganisés à la sauvegarde
  • Refactorings : renommage, extraction, et autres actions de code

Étape 7 : Intégration CI/CD

GitHub Actions

Créez .github/workflows/lint.yml :

name: Lint & Format
 
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
 
jobs:
  biome:
    name: Biome Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Setup Biome
        uses: biomejs/setup-biome@v2
        with:
          version: latest
 
      - name: Run Biome
        run: biome ci .

La commande biome ci est optimisée pour les pipelines CI : elle n'écrit pas de fichiers, produit un rapport de diagnostics et retourne un code d'erreur non nul si des problèmes sont détectés.

GitLab CI

Ajoutez dans .gitlab-ci.yml :

biome:
  stage: validate
  image: node:20-slim
  before_script:
    - npm ci
  script:
    - npx @biomejs/biome ci .
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

Pre-commit hook avec Husky

# Installer Husky
npm install --save-dev husky
npx husky init
 
# Ajouter le hook pre-commit
echo "npx @biomejs/biome check --staged --no-errors-on-unmatched" > .husky/pre-commit

Le flag --staged ne vérifie que les fichiers en staging, ce qui rend le hook quasi-instantané.


Étape 8 : Configuration avancée

Overrides par dossier

Biome permet des configurations différentes selon les dossiers ou les patterns de fichiers :

{
  "overrides": [
    {
      "include": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts"],
      "linter": {
        "rules": {
          "suspicious": {
            "noExplicitAny": "off"
          }
        }
      }
    },
    {
      "include": ["scripts/**"],
      "linter": {
        "rules": {
          "suspicious": {
            "noConsoleLog": "off"
          }
        }
      }
    },
    {
      "include": ["**/*.config.ts", "**/*.config.js"],
      "formatter": {
        "lineWidth": 120
      }
    }
  ]
}

Ignorer des fichiers

{
  "files": {
    "ignore": [
      "node_modules",
      ".next",
      "dist",
      "build",
      "coverage",
      "*.min.js",
      "generated/**"
    ]
  },
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  }
}

Avec "useIgnoreFile": true, Biome respecte automatiquement votre .gitignore.

Configuration monorepo

Pour un monorepo, placez biome.json à la racine et utilisez extends dans les packages :

my-monorepo/
├── biome.json              # Configuration de base
├── packages/
│   ├── web/
│   │   └── biome.json      # Étend la config racine
│   ├── api/
│   │   └── biome.json      # Étend la config racine
│   └── shared/
│       └── biome.json      # Étend la config racine
// packages/web/biome.json
{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "extends": ["../../biome.json"],
  "linter": {
    "rules": {
      "a11y": {
        "recommended": true
      }
    }
  }
}

Étape 9 : Configuration complète pour Next.js

Voici une configuration biome.json complète et prête pour la production avec Next.js :

{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  },
  "files": {
    "ignoreUnknown": true,
    "ignore": [
      ".next/**",
      "node_modules/**",
      "public/**",
      ".contentlayer/**"
    ]
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "lineEnding": "lf"
  },
  "organizeImports": {
    "enabled": true
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "double",
      "semicolons": "always",
      "trailingCommas": "all",
      "arrowParentheses": "always",
      "bracketSpacing": true
    }
  },
  "json": {
    "formatter": {
      "trailingCommas": "none"
    }
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedVariables": "error",
        "noUnusedImports": "error",
        "useExhaustiveDependencies": "warn"
      },
      "style": {
        "useConst": "error",
        "useImportType": "error",
        "noNonNullAssertion": "warn"
      },
      "suspicious": {
        "noExplicitAny": "warn",
        "noConsoleLog": "warn"
      },
      "nursery": {
        "useSortedClasses": {
          "level": "warn",
          "options": {
            "attributes": ["className"],
            "functions": ["clsx", "cn", "cva"]
          }
        }
      }
    }
  },
  "overrides": [
    {
      "include": ["**/*.test.ts", "**/*.test.tsx"],
      "linter": {
        "rules": {
          "suspicious": {
            "noExplicitAny": "off",
            "noConsoleLog": "off"
          }
        }
      }
    }
  ]
}

Étape 10 : Benchmark — ESLint + Prettier vs Biome

Mesurons la différence de performance sur un projet réel. Créez un script de benchmark :

#!/bin/bash
# benchmark.sh
 
echo "=== Benchmark : 500 fichiers TypeScript ==="
echo ""
 
# Créer des fichiers de test
mkdir -p bench-files
for i in $(seq 1 500); do
  cat > "bench-files/file-$i.tsx" << 'CONTENT'
import { useState, useEffect, useCallback } from "react";
import Link from "next/link";
import { z } from "zod";
 
const schema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  age: z.number().min(0).max(150),
});
 
type FormData = z.infer<typeof schema>;
 
export function UserForm({ onSubmit }: { onSubmit: (data: FormData) => void }) {
  const [data, setData] = useState<FormData>({ name: "", email: "", age: 0 });
  const [errors, setErrors] = useState<string[]>([]);
 
  const validate = useCallback(() => {
    const result = schema.safeParse(data);
    if (!result.success) {
      setErrors(result.error.errors.map((e) => e.message));
      return false;
    }
    setErrors([]);
    return true;
  }, [data]);
 
  useEffect(() => {
    validate();
  }, [validate]);
 
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        if (validate()) onSubmit(data);
      }}
    >
      <input
        type="text"
        value={data.name}
        onChange={(e) => setData({ ...data, name: e.target.value })}
      />
      <input
        type="email"
        value={data.email}
        onChange={(e) => setData({ ...data, email: e.target.value })}
      />
      <Link href="/users">Retour</Link>
      {errors.map((err) => (
        <p key={err}>{err}</p>
      ))}
    </form>
  );
}
CONTENT
done
 
echo "--- ESLint + Prettier ---"
time npx eslint bench-files/ 2>/dev/null
time npx prettier --check bench-files/ 2>/dev/null
 
echo ""
echo "--- Biome ---"
time npx @biomejs/biome check bench-files/
 
# Nettoyage
rm -rf bench-files

Résultats typiques

Outil500 fichiers1000 fichiers5000 fichiers
ESLint~8s~18s~95s
Prettier~3s~7s~35s
ESLint + Prettier~11s~25s~130s
Biome~0.4s~0.8s~3.5s

Biome est environ 25 à 35 fois plus rapide grâce à son architecture Rust et son parsing parallèle.


Dépannage

Problèmes courants

Le formatage est différent de Prettier

Biome vise la compatibilité avec Prettier mais quelques cas limites diffèrent. Si une différence spécifique vous bloque :

{
  "formatter": {
    "attributePosition": "multiline"
  }
}

Conflit avec l'extension Prettier dans VS Code

Désactivez l'extension Prettier ou limitez-la à des langages non supportés par Biome :

{
  "prettier.disableLanguages": [
    "javascript",
    "typescript",
    "javascriptreact",
    "typescriptreact",
    "json"
  ]
}

Les règles ESLint personnalisées ne sont pas migrées

Certaines règles spécifiques à des plugins ESLint tiers ne sont pas encore supportées par Biome. Consultez la matrice de compatibilité sur le site officiel pour vérifier le support de vos règles.

Erreur "file too large"

Par défaut, Biome ignore les fichiers de plus de 1 Mo. Ajustez si nécessaire :

{
  "files": {
    "maxSize": 2097152
  }
}

Prochaines étapes

Maintenant que Biome est configuré dans votre projet :

  • Explorez les règles nursery : de nouvelles règles sont ajoutées à chaque version, comme useSortedClasses pour trier les classes Tailwind
  • Configurez les hooks Git pour que chaque commit soit automatiquement vérifié
  • Ajoutez le support CSS : Biome supporte désormais le linting et formatage CSS/SCSS (expérimental)
  • Essayez biome search : recherche structurelle dans votre code avec des patterns GritQL
  • Contribuez : Biome est open source et accueille les contributions sur GitHub

Conclusion

Biome représente un changement de paradigme dans les outils JavaScript. En remplaçant ESLint et Prettier par un seul outil écrit en Rust, vous obtenez :

  • Une vitesse 25 à 35 fois supérieure sur le linting et le formatage
  • Une configuration simplifiée avec un seul fichier biome.json
  • Zéro conflit entre linter et formateur
  • Des diagnostics plus clairs avec des suggestions de correction intégrées
  • Un écosystème unifié qui s'étend au CSS, GraphQL et bientôt HTML

La migration depuis ESLint + Prettier est progressive et assistée par les outils de migration automatique. En 2026, Biome est devenu le choix par défaut pour les nouveaux projets et une mise à jour recommandée pour les projets existants.


Vous voulez lire plus de tutoriels? Découvrez notre dernier tutoriel sur Creer un Podcast a partir d'un PDF avec Vercel AI SDK et LangChain.

Discutez de votre projet avec nous

Nous sommes ici pour vous aider avec vos besoins en développement Web. Planifiez un appel pour discuter de votre projet et comment nous pouvons vous aider.

Trouvons les meilleures solutions pour vos besoins.

Articles connexes

Construire un Agent IA Autonome avec Agentic RAG et Next.js

Apprenez a construire un agent IA qui decide de maniere autonome quand et comment recuperer des informations depuis des bases de donnees vectorielles. Un guide pratique complet avec Vercel AI SDK et Next.js, accompagne d'exemples executables.

30 min read·