Runtime & Tools

Bun mit Claude Code: Der schnellste JavaScript-Runtime 2026

5. Mai 2026 9 min Lesezeit Runtime & Tools
Zurueck zum Blog

JavaScript-Entwicklung war jahrelang mit einem stillen Seufzen verbunden: npm install dauert ewig, der Test-Runner muss separat konfiguriert werden, die TypeScript-Transpilierung braucht einen extra Build-Schritt, und Node.js ist zwar zuverlaessig, aber nicht gerade bekannt fuer Geschwindigkeit. Bun hat das in weniger als drei Jahren fundamental veraendert.

Gemeinsam mit Claude Code entsteht ein Workflow, der JavaScript-Projekte auf ein neues Geschwindigkeitsniveau hebt — vom ersten bun init bis zum finalen Deployment. In diesem Artikel schauen wir uns an, was Bun wirklich kann, wie die wichtigsten Features in der Praxis aussehen und wie eine Migration von Node.js gelingt.

1. Was ist Bun? Der All-in-one-Ansatz

Bun ist kein weiterer JavaScript-Runtime-Klon. Es ist ein vollstaendiges JavaScript-Toolchain in einer einzigen Binary: Runtime, Package Manager, Bundler und Test-Runner gleichzeitig — geschrieben in Zig, gebaut auf JavaScriptCore (dem Engine aus WebKit/Safari statt V8), und darauf optimiert, eben schnell zu sein.

Vier Tools. Eine Binary.

Runtime Package Manager Bundler Test Runner

Statt node + npm + webpack/vite + jest/vitest einzeln zu installieren und zu konfigurieren, liefert bun alles in einer Binary — und jede dieser Komponenten ist auf Geschwindigkeit ausgelegt.

Benchmark: Bun vs. Node.js vs. Deno

Geschwindigkeitsversprechen klingen immer gut — aber was sagen reale Benchmarks? Stand Anfang 2026 (Bun 1.2.x) liefern unabhaengige Benchmarks folgende Richtwerte:

Benchmark Bun 1.2 Node.js 22 Deno 2
HTTP-Requests/s (hello world) ~127.000 req/s ~54.000 req/s ~73.000 req/s
SQLite-Reads/s (in-process) ~680.000 ops/s ~210.000 ops/s ~290.000 ops/s
Package Install (React-Projekt) ~0,3 s ~8,1 s ~2,4 s
TypeScript-Datei starten (kalt) ~28 ms ~310 ms ~95 ms
Hinweis zu Benchmarks: Zahlen variieren je nach Hardware, Workload und Konfiguration. Die Kernaussage bleibt jedoch konsistent: Bun ist in IO-intensiven und startup-sensitiven Szenarien deutlich schneller als Node.js.

Der Grund: JavaScriptCore hat eine aggressivere JIT-Strategie fuer kurzlebige Prozesse, und Bun's I/O-Layer ist direkt auf Linux io_uring / macOS kqueue aufgesetzt — ohne Node.js's libuv als Zwischenschicht.

2. Installation und erstes Setup

Bun ist als einzelne Binary verfuegbar und braucht keine globalen npm-Abhaengigkeiten. Die Installation dauert Sekunden.

Installation

Terminal Shell
# macOS / Linux (curl-Installer) curl -fsSL https://bun.sh/install | bash # Windows (PowerShell) powershell -c "irm bun.sh/install.ps1 | iex" # Via npm (falls bereits installiert) npm install -g bun # Version prüfen bun --version # 1.2.x

Neues Projekt initialisieren

Terminal Shell
bun init my-project # Interaktiv: Name, Einstiegspunkt, TypeScript? (ja/nein) cd my-project # Oder non-interaktiv mit Defaults: bun init -y

Das erzeugte package.json enthaelt bereits ein korrektes "type": "module" und einen TypeScript-freundlichen Einstiegspunkt. Kein tsconfig.json noetig — Bun versteht TypeScript nativ, ohne separaten Compiler-Schritt.

Scripts ausfuehren

Terminal + package.json Beispiel
// package.json scripts: { "scripts": { "dev": "bun run --watch src/index.ts", "build": "bun build src/index.ts --outdir dist", "test": "bun test", "start": "bun src/index.ts" } } # Ausfuehren: bun run dev bun run build

Automatisches .env-Loading

Einer der unterschaetzten Komfort-Features: Bun laedt .env automatisch — kein dotenv-Package noetig, kein require('dotenv').config().

src/config.ts TypeScript
// .env enthaelt: DATABASE_URL=postgres://localhost/mydb // API_KEY=secret-key-123 // In deinem Code — einfach lesen: const dbUrl = process.env.DATABASE_URL; const apiKey = process.env.API_KEY; // Oder mit Bun's eigenem Env-Objekt: const port = Bun.env.PORT ?? "3000"; // Bun laedt automatisch (in Reihenfolge): // .env.local -> .env.{NODE_ENV} -> .env
Claude Code + Bun Tip: Claude Code erkennt automatisch, ob ein Projekt Bun verwendet (anhand von bun.lockb oder bun.lock), und nutzt dann bun run statt npm run in vorgeschlagenen Commands.

3. Bun als Package Manager

Der Package Manager ist oft der erste Kontaktpunkt mit Bun — und der Geschwindigkeitsunterschied ist sofort spuerbar. Bun cached aggressiv lokal und parallelisiert Downloads maximal.

Grundlegende Befehle

Terminal Package Manager
# Alle Dependencies installieren (aus package.json) bun install # Package hinzufuegen bun add express bun add -d @types/express # Dev-Dependency bun add -g typescript # Global # Package entfernen bun remove express # Package aktualisieren bun update bun update react # Einzelnes Package # Installierte Packages auflisten bun pm ls

Das Lockfile: bun.lockb

Bun nutzt ein binaeres Lockfile (bun.lockb), das wesentlich kompakter als package-lock.json oder yarn.lock ist. Ab Bun 1.1 gibt es optional auch ein textbasiertes bun.lock fuer bessere Git-Diffs.

Terminal Lockfile
# Textbasiertes Lockfile aktivieren (bun.lock statt bun.lockb) bun install --save-text-lockfile # Lockfile verifizieren (CI-Umgebungen) bun install --frozen-lockfile # Lockfile ausgeben (YAML-aehnlich) bun pm print-lockfile

Workspaces fuer Monorepos

Bun unterstuetzt npm-kompatible Workspaces nativ — ideal fuer Monorepo-Setups mit mehreren Paketen.

package.json (Root) Monorepo
{ "name": "my-monorepo", "workspaces": [ "packages/*", "apps/*" ] }
Terminal — Workspace Commands Workspaces
# Alle Workspaces installieren (ein Befehl, Root-Ebene) bun install # Script in einem spezifischen Workspace ausfuehren bun run --filter "@myrepo/api" dev bun run --filter "./apps/web" build # Alle Workspaces bauen bun run --filter "*" build # Package zu einem Workspace hinzufuegen bun add zod --cwd packages/shared

Warum bun install so schnell ist

Bun nutzt einen globalen Cache auf dem Dateisystem und Hard-Links statt Kopien in node_modules. Nach dem ersten Install einer Package-Version landen alle weiteren Projekte, die dieselbe Version nutzen, bei einem Hard-Link — kein Re-Download, minimaler Disk-Overhead.

In CI-Umgebungen ist bun install oft 10–25x schneller als npm install — wenn der Cache warm ist, sogar noch schneller.

4. Bun APIs: Das Standard-Toolkit

Neben Node.js-Kompatibilitaet bietet Bun eine eigene, hochperformante API-Schicht — Bun.* Namespaced — fuer die haeufigsten Aufgaben: Dateizugriff, HTTP-Server, SQLite, Kryptographie, und mehr.

Bun.file()
Lazy File-Handle mit Stream-, Text- und JSON-Zugriff ohne extra Import
Bun.serve()
HTTP/HTTPS/WebSocket-Server mit eingebautem TLS — kein Express noetig
Bun.sqlite()
In-process SQLite mit synchronen Queries — schnellste embedded DB in JS
Bun.password
bcrypt / argon2 Hashing nativ, ohne native bindings
Bun.hash()
WYHASH, CRC32, Adler32, Murmur — ultraschnelle non-cryptographic hashes
Bun.spawn()
Subprocess API mit Pipe-Support und async/await Interface

Bun.file() — Dateizugriff ohne Boilerplate

src/files.ts Bun API
// Datei lesen — verschiedene Formate const file = Bun.file("./data/config.json"); const text = await file.text(); // als String const json = await file.json(); // direkt als Objekt const buffer = await file.arrayBuffer(); // als ArrayBuffer const stream = file.stream(); // als ReadableStream // Datei schreiben await Bun.write("./output/result.json", { status: "ok" }); await Bun.write("./output/log.txt", "Log entry\n"); // Existenz pruefen const exists = await Bun.file("./config.json").exists();

Bun.serve() — HTTP-Server in wenigen Zeilen

src/server.ts HTTP Server
const server = Bun.serve({ port: 3000, hostname: "0.0.0.0", async fetch(req: Request): Promise<Response> { const url = new URL(req.url); if (url.pathname === "/api/health") { return Response.json({ ok: true, runtime: "bun" }); } if (url.pathname === "/api/file") { const file = Bun.file("./public/index.html"); return new Response(file); // lazy stream — kein read noetig! } return new Response("Not Found", { status: 404 }); }, // WebSocket-Support eingebaut: websocket: { message(ws, msg) { ws.send(`Echo: ${msg}`); }, open(ws) { console.log("Client connected"); }, close(ws) { console.log("Client disconnected"); }, } }); console.log(`Server listening on port ${server.port}`);

Bun.sqlite() — Embedded Database

src/db.ts SQLite
import { Database } from "bun:sqlite"; const db = new Database("./data/app.db"); // In-memory: new Database(":memory:") // Schema erstellen db.run(` CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT UNIQUE NOT NULL, created_at TEXT DEFAULT (datetime('now')) ) `); // Prepared Statements (wiederverwendbar, sehr schnell) const insertUser = db.prepare( "INSERT INTO users (name, email) VALUES ($name, $email)" ); const getUser = db.prepare( "SELECT * FROM users WHERE email = $email" ); insertUser.run({ $name: "Alice", $email: "alice@example.com" }); const user = getUser.get({ $email: "alice@example.com" }); console.log(user); // { id: 1, name: "Alice", ... }

Bun.password — Sicheres Hashing

src/auth.ts Security
// Passwort hashen (Standard: bcrypt) const hash = await Bun.password.hash("user-password-123"); // Verifizieren const valid = await Bun.password.verify("user-password-123", hash); // true // Argon2 (moderner, empfohlen fuer neue Projekte) const argonHash = await Bun.password.hash("password", { algorithm: "argon2id", memoryCost: 65536, timeCost: 2, });

5. Bun Test Runner: bun:test

Kein separates Testing-Framework mehr installieren. bun test ist der integrierte Test-Runner mit einer Jest-kompatiblen API — was bedeutet, dass bestehende Jest-Tests ohne Aenderung laufen.

Grundstruktur

src/__tests__/calculator.test.ts Tests
import { describe, it, expect, beforeEach } from "bun:test"; import { Calculator } from "../calculator"; describe("Calculator", () => { let calc: Calculator; beforeEach(() => { calc = new Calculator(); }); it("adds two numbers", () => { expect(calc.add(2, 3)).toBe(5); }); it("throws on division by zero", () => { expect(() => calc.divide(10, 0)).toThrow("Division by zero"); }); it("handles async operations", async () => { const result = await calc.fetchRate("USD"); expect(result).toBeGreaterThan(0); }); });

Mocks und Spies

src/__tests__/mocks.test.ts Mocking
import { mock, spyOn, jest } from "bun:test"; // Funktion mocken const fetchData = mock(async () => ({ id: 1, name: "Test" })); it("calls mock function", async () => { const data = await fetchData(); expect(fetchData).toHaveBeenCalled(); expect(data.name).toBe("Test"); }); // Modul-Methode spionieren import * as myModule from "../myModule"; const spy = spyOn(myModule, "processData").mockReturnValue("mocked"); // Timer mocken jest.useFakeTimers(); jest.advanceTimersByTime(1000); jest.useRealTimers();

Snapshots und Coverage

Terminal — Test-Runner Flags Runner
# Alle Tests ausfuehren bun test # Watch-Modus (bei Dateiänderungen re-run) bun test --watch # Spezifische Datei oder Pattern bun test src/__tests__/calculator.test.ts bun test --test-name-pattern "adds two" # Coverage-Report bun test --coverage # Timeout setzen (ms) bun test --timeout 5000 # Bail nach N Fehlern bun test --bail 3 # Snapshots aktualisieren bun test --update-snapshots

Jest-Kompatibilitaet im Detail

Bun's bun:test implementiert den groeßten Teil der Jest-API: describe, it/test, expect, beforeEach/afterEach, beforeAll/afterAll, Mocks, Spies, Fake Timers und Snapshots. Die meisten bestehenden Jest-Test-Dateien laufen nach Aendern des Import-Pfads von @jest/globals auf bun:test sofort.

Wichtig: Coverage-Reports sind noch nicht so ausgereift wie in Jest — fuer detaillierte Coverage-Anforderungen (z.B. Branch Coverage in CI) ggf. nyc/c8 als Post-Processor nutzen.

6. Migration von Node.js zu Bun

Bun ist darauf ausgelegt, als Drop-in-Replacement fuer Node.js zu funktionieren. In der Praxis bedeutet das: Die meisten Node.js-Projekte laufen ohne Code-Aenderungen mit Bun. Es gibt aber Ausnahmen, die zu kennen sich lohnt.

Was funktioniert ohne Aenderung

CommonJS require() ES Modules import Node.js Built-ins (fs, path, http...) npm Packages TypeScript nativ JSX/TSX nativ process.env Buffer API

Bun implementiert die Node.js API-Oberflaeche vollstaendig — inklusive fs, path, os, crypto, http, https, stream, events, child_process und mehr.

Schritt-fuer-Schritt Migration

1

Bun installieren und Runtime tauschen

Statt node src/index.js einfach bun src/index.js verwenden. In package.json Scripts node durch bun ersetzen.

2

Package Manager migrieren

rm -rf node_modules package-lock.json && bun install — das erzeugt bun.lockb und richtet den schnelleren Cache ein.

3

dotenv entfernen

Falls dotenv nur fuer .env-Loading genutzt wird: Package entfernen, require('dotenv').config() loeschen — Bun macht das automatisch.

4

Test-Runner migrieren

Jest-Tests funktionieren in der Regel direkt mit bun test. Import-Pfad von "@jest/globals" auf "bun:test" aendern fuer native Bun-Features.

5

TypeScript-Config aufraeumen

Da Bun TypeScript nativ versteht, kann ts-node, tsx, und ts-jest oft entfernt werden. Auch Build-Schritte fuer reine Entwicklung entfallen.

6

Native Module pruefen

Packages mit C/C++ native bindings (.node-Dateien) koennen Probleme machen. Alternativen in der Bun-Community suchen oder Node.js fuer diese Packages als Fallback nutzen.

Bekannte Limitierungen

Bekannte Limitierungen (Stand 2026-Q2):

Native Addons (.node): Packages die N-API-Bindings nutzen (z.B. manche Datenbank-Treiber, native crypto-Module) funktionieren moeglicherweise nicht vollstaendig.

Worker Threads API: Bun hat eine eigene Worker-Implementierung, die nicht 100% Node.js-kompatibel ist — Edge Cases moeglich.

vm-Modul: node:vm hat partielle Unterstuetzung. Komplexe Sandbox-Szenarien koennen abweichen.

Empfehlung: Fuer neue Projekte direkt mit Bun starten. Fuer bestehende Projekte: testen, dann schrittweise migrieren.

Bun in CI/CD: GitHub Actions

.github/workflows/ci.yml CI/CD
name: CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v2 with: bun-version: latest - name: Install dependencies run: bun install --frozen-lockfile - name: Run tests run: bun test --coverage - name: Build run: bun run build
CI/CD-Tipp: Statt actions/setup-node + npm ci genuegt oven-sh/setup-bun@v2 + bun install --frozen-lockfile. Pipeline-Zeit reduziert sich bei den meisten Projekten um 40-70%. Der globale Bun-Cache kann in GitHub Actions zusaetzlich gespeichert werden fuer noch schnellere Runs.

Fazit: Bun ist bereit fuer Production

Bun hat 2026 den Status "interessantes Experiment" hinter sich gelassen. Mit Version 1.2.x ist es stabil, Node.js-kompatibel genug fuer die grosse Mehrheit der Projekte, und in Geschwindigkeit und Developer Experience klar ueberlegen.

Wann Bun waehlen?

Sofort: Neue Projekte, APIs, CLI-Tools, Script-Automatisierung, serverless Functions, Monorepos.

Mit Testing: Bestehende Node.js-Projekte die aktiv weiterentwickelt werden — Migration ist meistens unter 30 Minuten.

Abwarten: Legacy-Systeme mit vielen native bindings oder vm-intensivem Einsatz — hier erst gruendlich testen.

Die Kombination mit Claude Code macht den Einstieg noch einfacher: Projekte initialisieren, migrieren, testen und deployen — alles unterstuetzt durch KI-assistiertes Tooling, das Bun als First-Class-Runtime behandelt. Wer heute mit einem neuen JavaScript-Projekt startet und auf modernen Tooling-Komfort ohne Konfigurationsaufwand setzt, sollte Bun als erste Wahl in Betracht ziehen.

KI-assistierte Entwicklung mit Bun starten

Erlebe wie Claude Code und Bun zusammen JavaScript-Entwicklung auf ein neues Level heben — von der ersten Zeile bis zum Production-Deploy.

Jetzt kostenlos testen →
Alle Artikel im Blog