La nouvelle que personne n’avait vue venir

La semaine passée, pendant qu’on se battait tranquillement avec le node_modules, Anthropic a balancé une bombe : ils ont acheté Bun.

Eh oui, la boîte derrière Claude a décidé que son avenir passait par un runtime JavaScript écrit en Zig par un type qui s’est dit “Et si Node, mais rapide ?”. Claude Code vient d’atteindre un milliard de dollars de chiffre d’affaires, et apparemment quand t’as trop de thune qui traîne, tu t’achètes des outils de développement.

Pourquoi ? Parce que Claude Code exécute du JavaScript à tout-va, et chaque milliseconde compte quand t’as des millions d’utilisateurs. Dit autrement : si ton business dépend d’exécuter du code rapidement, tu t’achètes le runtime le plus rapide.

Mais bon, assez de ragots d’entreprise. Passons à ce qui t’intéresse : c’est quoi Bun et pourquoi ça devrait te préoccuper.

C’est quoi Bun (pour ceux qui viennent de Node)

Bun c’est comme si quelqu’un avait regardé l’écosystème Node et s’était dit : “Et si au lieu d’avoir quinze outils on en faisait un seul qui les remplace tous ?”

Là où avant t’avais :

node          → runtime
npm/pnpm/yarn → gestionnaire de paquets
webpack/esbuild/vite → bundler
jest/vitest   → test runner
ts-node/tsx   → exécuter TypeScript

Maintenant t’as :

bun           → tout ce qui précède

C’est la trottinette électrique face à la voiture avec remorque. Moins de pièces, moins de trucs qui peuvent foirer, et bizarrement plus rapide.

Les chiffres qui comptent

J’aime pas faire de benchmarks parce qu’on peut toujours les trafiquer. Mais ces chiffres sont tellement brutaux qu’ils méritent d’être mentionnés :

OpérationNode + pnpmBunDifférence
install (projet moyen)~25s~3s8x plus rapide
Démarrage du runtime~50ms~5ms10x plus rapide
Exécuter les testsbaseline2-3x plus rapideNotable
Transpiler TypeScriptFaut un outilNatif

Pourquoi c’est si rapide ? Parce que c’est écrit en Zig au lieu de C++, et parce que Jarred Sumner (le créateur) c’est un de ces programmeurs qui optimise le code comme hobby. Le gars bossait chez Stripe et a décidé que le problème le plus important au monde c’était que npm install mettait trop de temps.

Et puis bon, peut-être qu’il avait raison.

Ce qui fonctionne déjà (et ce qui fonctionne pas)

Bun est compatible avec la plupart des APIs de Node. Si ton code utilise fs, path, http, ou n’importe quel module standard, ça marchera probablement sans changement.

Ça fonctionne bien

  • Next.js : Support officiel. bun run dev et c’est parti.
  • Express/Fastify : Sans problème.
  • La plupart des paquets npm : Bun lit package.json et node_modules pareil que Node.
  • TypeScript : Natif, sans configuration.
  • JSX : Aussi natif.

Ça peut poser problème

  • Paquets avec des bindings natifs de Node : Certains ont besoin d’être recompilés.
  • Code qui dépend de bizarreries spécifiques de V8 : Bun utilise JavaScriptCore (le moteur de Safari).
  • Quelques APIs de Node très spécifiques : Workers, certaines parties de cluster.

Ça fonctionne pas (encore)

  • Windows : Ça fonctionne, mais avec quelques limitations.
  • Yarn PnP : Pas supporté.

Ton premier projet avec Bun

Si t’as déjà Node, installer Bun c’est une commande :

1
curl -fsSL https://bun.sh/install | bash

Ou si t’es sur macOS avec Homebrew :

1
brew install oven-sh/bun/bun

Vérifie que ça marche :

1
bun --version

Créer un projet nouveau

1
2
mkdir mon-projet && cd mon-projet
bun init

Ça te génère un package.json, un tsconfig.json, et un index.ts. Sans questions, sans wizards. J’aime bien.

Le fichier qu’il génère

1
2
// index.ts
console.log("Hello via Bun!");

Exécute-le :

1
bun run index.ts

Ouais, il exécute TypeScript directement. Sans transpiler. Sans ts-node. Sans rien.

Migrer depuis pnpm

Si t’as un projet avec pnpm, la migration est étonnamment simple :

1
2
3
4
5
6
# Option 1 : Régénérer le lockfile
rm -rf node_modules pnpm-lock.yaml
bun install

# Option 2 : Utiliser le lockfile existant (expérimental)
bun install

Bun génère son propre bun.lockb (binaire, plus rapide à parser). Tu peux garder les deux lockfiles pendant la transition si tu bosses en équipe et que tout le monde n’a pas encore migré.

Le package.json change pas

1
2
3
4
5
6
7
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "test": "vitest"
  }
}

Tu continues à exécuter bun run dev, bun run build, bun run test. Les scripts fonctionnent pareil.

Tests : de Vitest à Bun

Bun a son propre test runner qui est compatible avec l’API de Jest/Vitest :

1
2
3
4
5
6
7
// sum.test.ts
import { expect, test } from "bun:test";
import { sum } from "./sum";

test("2 + 2 = 4", () => {
  expect(sum(2, 2)).toBe(4);
});

Exécute avec :

1
bun test

Et si je veux garder Vitest ?

Ça marche parfaitement. Bun peut exécuter Vitest comme runtime :

1
bun run vitest

Tu récupères la vitesse de démarrage de Bun avec les fonctionnalités de Vitest. Le meilleur des deux mondes.

Le serveur HTTP le plus rapide que tu verras

Bun inclut un serveur HTTP qui laisse Express pleurer dans un coin :

1
2
3
4
5
6
7
8
Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Salut depuis Bun !");
  },
});

console.log("Serveur sur http://localhost:3000");

Il utilise l’API standard de fetch (Request/Response), donc si tu viens de Cloudflare Workers ou Deno, tu te sentiras chez toi.

Benchmark de hello world

Sur ma machine (M1 Pro), un serveur de hello world :

  • Express : ~15'000 req/s
  • Fastify : ~45'000 req/s
  • Bun.serve : ~150'000 req/s

Ouais, dix fois plus rapide qu’Express. Non, c’est pas une faute de frappe.

Variables d’environnement

Bun charge .env automatiquement. Sans dotenv. Sans configuration.

1
2
# .env
DATABASE_URL=postgres://localhost/mydb
1
2
// index.ts
console.log(Bun.env.DATABASE_URL);

C’est tout. Ça marche et point final.

SQLite intégré

Ça m’a explosé la tête. Bun embarque SQLite :

1
2
3
4
5
6
7
8
import { Database } from "bun:sqlite";

const db = new Database("mydb.sqlite");
db.run("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
db.run("INSERT INTO users (name) VALUES (?)", ["Fernando"]);

const users = db.query("SELECT * FROM users").all();
console.log(users);

Pas besoin d’installer better-sqlite3 ou sql.js. Ça marche simplement.

Le bundler

Bun peut aussi empaqueter ton code pour la production :

1
bun build ./index.ts --outdir ./dist

C’est plus rapide qu’esbuild (qui était déjà ridiculement rapide). Pour la plupart des projets, ça génère des bundles équivalents.

Si t’as besoin de quelque chose de plus sophistiqué (code splitting, tree shaking avancé), t’auras probablement encore besoin de Vite ou webpack. Mais pour beaucoup de cas, ça suffit.

Quand PAS utiliser Bun

Parce que c’est pas que des arcs-en-ciel et des licornes :

  1. Production critique où tu peux pas expérimenter : Bun est stable, mais Node a 15 ans de bugs résolus.

  2. Paquets avec des bindings natifs très spécifiques : Certains demandent du boulot supplémentaire.

  3. Windows comme plateforme principale : Ça marche, mais le support de première classe c’est pour macOS/Linux.

  4. Ton équipe veut rien apprendre de nouveau : Parfois le meilleur outil c’est celui que tout le monde sait utiliser.

Quand OUI utiliser Bun

  1. CI/CD : Le temps d’install réduit fait économiser de la vraie thune. Sérieusement, fais le calcul.

  2. Scripts et outils internes : La vitesse de démarrage fait que les scripts semblent instantanés.

  3. Projets nouveaux sans legacy : Commencer avec Bun c’est plus simple que commencer avec Node + npm + tsx + vitest + …

  4. Serverless/Edge : Moins de temps de démarrage = moins de cold starts = moins de latence = utilisateurs plus contents.

  5. Maintenant qu’Anthropic est derrière : C’est pas rien. Ils ont de la thune, ils ont des incitations, et ils ont un produit (Claude Code) qui dépend du fait que Bun soit bon.

Ma recommandation

Si tu commences un nouveau projet et t’as pas de contraintes d’équipe, teste Bun. Le pire qui puisse arriver c’est que tu reviennes à Node, et t’auras appris quelque chose.

Si t’as un projet existant en production, évalue d’abord en CI/CD. C’est là où on voit le plus la différence et où il y a le moins de risque. Si bun install marche bien avec tes dépendances, t’as déjà gagné.

Et si t’es du genre à aimer vivre à la limite, mets-le en production et raconte-moi comment ça se passe. Moi j’ose encore pas, mais j’ai les doigts croisés.

Ressources

Conclusion

Bun c’est ce qui arrive quand quelqu’un regarde l’écosystème JavaScript et décide qu’on peut faire mieux. Et ce qui inquiète c’est que… il a raison.

C’est la fin de Node ? Probablement pas. Node va pas disparaître comme Java n’a pas disparu quand est sorti… bon, n’importe quoi. Mais c’est le premier concurrent sérieux depuis longtemps.

Et maintenant qu’Anthropic est derrière, avec ses milliards de dollars et son besoin que JavaScript vole, ça devient intéressant.

En attendant, je vais continuer à utiliser pnpm en production. Mais mes scripts locaux tournent déjà avec Bun, et mon CI est en cours de migration. Petit à petit.


TL;DR : Bun c’est un runtime JavaScript tout-en-un (runtime + package manager + bundler + test runner) qui est significativement plus rapide que Node. Anthropic vient de l’acheter. Ça marche avec la plupart des projets TypeScript existants. Teste-le en CI d’abord, c’est là où on le sent le plus.