Bun Runtime avec Claude Code : adoption pratique
Adopter Bun avec Claude Code : Bun.serve, scripts package, tests, compatibilité Node, pièges et rollout.
Bun n’est pas seulement un runtime JavaScript rapide. En pratique, il regroupe runtime, gestionnaire de paquets, exécution de scripts, test runner et bundler. Pour débuter : le runtime exécute JavaScript ou TypeScript, un package script est un raccourci dans package.json, et un test runner lance les tests.
Avec Claude Code, l’approche prudente consiste à éviter le remplacement complet de Node.js au premier jour. Commencez par une preuve limitée : bun run pour les scripts, une petite API Bun.serve, bun test, puis une revue des risques de compatibilité Node. Les références officielles sont la documentation Bun, Bun.serve, bun run, Bun test runner et la compatibilité Node.js.
Pour continuer, lisez aussi le guide API Claude Code, les stratégies de test et le guide performance.
Commencer par un périmètre réversible
Demandez d’abord une analyse :
Analyse ce dépôt pour une adoption progressive de Bun. Ne modifie encore aucun fichier. Lis
package.json, lockfiles, tests, CI, Docker et usages des APIs Node. Retourne un tableau avec candidats sûrs, candidats risqués et commandes de vérification.
| Étape | Essai | Succès |
|---|---|---|
| 1 | bun install dans une branche | Le diff de dépendances est compris |
| 2 | bun run pour les scripts | Le sens des scripts ne change pas |
| 3 | bun test sur des tests ciblés | Les écarts avec Jest sont visibles |
| 4 | Bun.serve pour une petite API | Le comportement HTTP est vérifiable |
Exemple Bun.serve copiable
mkdir bun-claude-lab
cd bun-claude-lab
bun init -y
{
"name": "bun-claude-lab",
"type": "module",
"scripts": {
"dev": "bun --watch src/server.ts",
"start": "bun src/server.ts",
"test": "bun test",
"check": "bun test && bun run scripts/runtime-check.ts"
}
}
// src/server.ts
function json(data: unknown, status = 200): Response {
return Response.json(data, {
status,
headers: { "Cache-Control": "no-store" }
});
}
const server = Bun.serve({
port: Number(process.env.PORT ?? 3000),
async fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/health") {
return json({ ok: true, runtime: "bun" });
}
if (url.pathname === "/api/echo" && req.method === "POST") {
const body = (await req.json().catch(() => null)) as { message?: string } | null;
if (!body?.message) {
return json({ error: "message is required" }, 400);
}
return json({
message: body.message.trim(),
receivedAt: new Date().toISOString()
}, 201);
}
return json({ error: "not_found", pathname: url.pathname }, 404);
}
});
console.log(`Listening on ${server.url}`);
bun run dev
curl http://localhost:3000/health
curl -X POST http://localhost:3000/api/echo \
-H "Content-Type: application/json" \
-d '{"message":"hello from Bun"}'
Tests avec bun:test
// src/message.ts
export function normalizeMessage(input: string): string {
return input.trim().replace(/\s+/g, " ");
}
export function createReply(input: string): { message: string; length: number } {
const message = normalizeMessage(input);
if (!message) throw new Error("message must not be empty");
return { message, length: message.length };
}
// src/message.test.ts
import { describe, expect, test } from "bun:test";
import { createReply, normalizeMessage } from "./message";
describe("message helpers", () => {
test("normalizes whitespace", () => {
expect(normalizeMessage(" hello bun ")).toBe("hello bun");
});
test("creates a reply payload", () => {
expect(createReply(" Claude Code ")).toEqual({
message: "Claude Code",
length: 11
});
});
test("rejects empty messages", () => {
expect(() => createReply(" ")).toThrow("message must not be empty");
});
});
bun test
bun test --watch
Contrôle de compatibilité Node
// scripts/runtime-check.ts
import { existsSync } from "node:fs";
import { join } from "node:path";
const checks = [
["package.json exists", existsSync(join(process.cwd(), "package.json"))],
["Bun global is available", typeof Bun !== "undefined"],
["fetch is available", typeof fetch === "function"],
["Buffer is available", typeof Buffer !== "undefined"]
] as const;
for (const [label, ok] of checks) {
console.log(`${ok ? "PASS" : "FAIL"} ${label}`);
}
if (checks.some(([, ok]) => !ok)) {
process.exit(1);
}
bun run check
Trois cas d’usage
Premier cas : une API interne, un outil d’administration ou un webhook local. Bun.serve suffit pour /health, JSON et petites démos.
Deuxième cas : adoption progressive dans un projet Node.js. La production peut rester sur Node, pendant que bun install, bun run ou bun test accélèrent la boucle locale.
Troisième cas : documentation et formation. Un exemple court avec serveur, curl et tests aide le lecteur à comprendre la frontière du runtime.
Pièges à éviter
Ne supposez pas une compatibilité Node parfaite. Addons natifs, modules node:* moins courants, vieux paquets CommonJS et streaming doivent être testés.
Ne remplacez pas une grande suite Jest sans audit. Mocking, snapshots, fake timers et tests DOM peuvent nécessiter des adaptations.
Attention aux scripts. En équipe, bun run dev est plus clair que les raccourcis, et l’ordre des flags comme bun --watch run dev doit être documenté.
La vitesse ne remplace pas le rollout. CI, Docker, déploiement, monitoring et rollback restent des critères de production.
CTA et note de vérification
Pour pratiquer, commencez par le cheatsheet gratuit. Pour les prompts réutilisables, modèles CLAUDE.md et guides de setup, consultez la page produits en anglais. Pour une adoption en équipe, utilisez training et consultation.
Note pratique : bun n’est pas installé dans ce workspace. Je ne revendique donc pas d’exécution locale. Le sample se vérifie avec bun run dev, les deux commandes curl, bun test et bun run check.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Workflow Obsidian vers CLAUDE.md avec Claude Code
Transformer des notes Obsidian en notes CLAUDE.md concises pour reprendre les sessions sans réexpliquer.
Claude Code Revenue CTA Routing : relier articles, PDF, Gumroad et consultation
Un workflow Claude Code pour orienter les lecteurs vers PDF gratuit, Gumroad ou consultation selon l'intention.
Règles de handoff Claude Code en équipe: preuves, permissions, rollback et revenus
Un format concret pour transmettre un travail Claude Code avec preuves, permissions, rollback, PDF gratuit, Gumroad et consultation.