Native Ausführung ohne separaten Compile-Schritt, aber mit klaren Grenzen
Bun führt TypeScript-Dateien direkt aus, ohne dass vorher tsc oder ein Bundler laufen muss, was Entwicklungsschleifen spürbar verkürzt. Wichtig zu verstehen ist dabei, dass Bun TypeScript nur transpiliert, also Typen entfernt und Syntax übersetzt, aber keine Typprüfung durchführt, diese Verantwortung bleibt weiterhin bei einem separaten tsc-Aufruf oder der IDE.
Inhaltsverzeichnis
- 1. Wie Bun TypeScript ohne separaten Build ausführt
- 2. Transpilation ist kein Typecheck: die wichtigste Einschränkung
- 3. Wie Bun mit tsconfig.json und Compiler-Optionen umgeht
- 4. Tests direkt in TypeScript mit bun test
- 5. Node-Kompatibilität und typische Migrationsfallen
- 6. Watch-Modus und Hot Reload für schnellere Entwicklungsschleifen
- 7. Produktions-Builds trotzdem sinnvoll: bun build
- 8. IDE-Integration und der Typecheck im Editor
- 9. Wann sich Bun für TypeScript-Projekte lohnt
- 10. Zusammenfassung
- 11. FAQ
1. Wie Bun TypeScript ohne separaten Build ausführt
Bun basiert auf der JavaScriptCore-Engine und bringt einen eingebauten TypeScript-Transpiler mit, der beim Laden einer .ts-Datei die Typannotationen entfernt und modernes Syntax-Feature-Set direkt zu JavaScript übersetzt, bevor die Engine den Code ausführt. Dieser Schritt passiert intern, ohne dass ein separater tsc-Prozess gestartet oder ein Ausgabeverzeichnis mit kompilierten Dateien erzeugt wird.
Der entscheidende Unterschied zu einem klassischen ts-node- oder tsx-Setup unter Node.js ist, dass die Transpilation nativ in Bun eingebaut ist statt über ein zusätzliches npm-Paket zu laufen, was den Start deutlich beschleunigt. Bun cached zudem die transpilierten Module intern, sodass wiederholte Ausführungen desselben Skripts nicht jedes Mal neu transpiliert werden müssen.
# main.ts direkt ausführen, kein vorheriger Build-Schritt nötig
bun run main.ts
# Auch mit npm-Skripten funktioniert das identisch
bun run start # package.json: "start": "bun main.ts"
2. Transpilation ist kein Typecheck: die wichtigste Einschränkung
Der häufigste Irrtum bei Bun ist die Annahme, dass eine erfolgreich laufende .ts-Datei automatisch typkorrekt ist. Bun entfernt Typannotationen rein syntaktisch, es prüft nicht, ob ein Funktionsaufruf mit falschen Argumenttypen erfolgt oder ob ein Property-Zugriff auf einem möglicherweise undefinierten Wert stattfindet, solche Fehler führen zu einem Laufzeitcrash statt zu einem frühen Compile-Fehler.
Für echte Typsicherheit bleibt ein separater tsc --noEmit-Lauf notwendig, entweder lokal in der IDE, als Pre-Commit-Hook oder als eigener CI-Schritt. Dieser Lauf produziert keinen Output, sondern dient ausschließlich der Typprüfung, während Bun weiterhin für die eigentliche Ausführung zuständig bleibt.
# Bun führt diese Datei klaglos aus, obwohl der Typ falsch ist
# add(a: number, b: number) wird mit einem String aufgerufen
bun run buggy.ts # läuft, crasht ggf. erst bei falscher Nutzung
# Typfehler nur mit einem separaten tsc-Check sichtbar machen
npx tsc --noEmit
3. Wie Bun mit tsconfig.json und Compiler-Optionen umgeht
Bun liest die tsconfig.json eines Projekts für bestimmte Einstellungen, insbesondere paths für Modul-Aliase, baseUrl und jsx-bezogene Optionen, die das Laufzeitverhalten der Transpilation beeinflussen. Reine Typprüfungs-Optionen wie strict oder noImplicitAny haben dagegen keinerlei Effekt auf die Ausführung, weil Bun diese Regeln schlicht nicht auswertet.
Das führt zu einer wichtigen Trennung: tsconfig.json bleibt weiterhin die Konfigurationsquelle für den separaten Typecheck-Lauf mit tsc, während Bun sich nur die Teile herauszieht, die für korrekte Modulauflösung und Syntax-Transformation nötig sind.
{
"compilerOptions": {
"strict": true,
"paths": { "@app/*": ["src/*"] },
"baseUrl": "."
}
}
// Bun respektiert die paths-Aliase beim Ausführen,
// "strict" wirkt sich nur auf einen separaten tsc-Lauf aus
4. Tests direkt in TypeScript mit bun test
Der eingebaute Test-Runner bun test führt Testdateien in TypeScript ohne Build-Schritt aus und bringt eine zu Jest kompatible API mit, was den Umstieg von bestehenden Jest-Testsuiten in vielen Fällen ohne große Umschreibungen ermöglicht. Die Ausführungsgeschwindigkeit ist dabei durch die eingebaute Transpilation und die schnelle Engine typischerweise deutlich höher als bei einem Jest-Setup mit ts-jest.
Wichtig bleibt auch hier: bun test prüft keine Typen, ein Test mit einer falsch typisierten Assertion läuft trotzdem durch, solange die Laufzeitlogik stimmt. Ein separater Typecheck-Schritt in der CI-Pipeline bleibt deshalb auch bei Nutzung von bun test unverzichtbar.
import { describe, it, expect } from "bun:test";
import { add } from "./math";
describe("add", () => {
it("addiert zwei Zahlen korrekt", () => {
expect(add(2, 3)).toBe(5);
});
});
5. Node-Kompatibilität und typische Migrationsfallen
Bun implementiert einen großen Teil der Node.js-APIs, darunter fs, path und weite Teile von node:http, was viele bestehende Node-TypeScript-Projekte ohne große Anpassung lauffähig macht. Nicht jede Node-API ist jedoch vollständig oder identisch implementiert, insbesondere bei selteneren APIs aus worker_threads oder spezifischen stream-Verhaltensweisen können sich Unterschiede zeigen.
Bei der Migration eines bestehenden Node-Projekts lohnt sich, zunächst die Testsuite unter Bun laufen zu lassen, um Kompatibilitätslücken früh zu erkennen, statt sich blind auf vollständige Node-Äquivalenz zu verlassen. Bun aktualisiert seine Node-Kompatibilität fortlaufend, ein Blick in die aktuelle Kompatibilitätsübersicht vor einer Migration ist deshalb sinnvoll.
Ein pragmatischer Zwischenschritt für größere Migrationen ist, Bun zunächst nur für lokale Entwicklung und die Testsuite einzusetzen, während die Produktionsumgebung vorerst weiter unter Node läuft. So lässt sich der Geschwindigkeitsgewinn im Entwicklungsalltag sofort nutzen, ohne das Produktionsrisiko einer vollständigen Runtime-Umstellung auf einen Schlag einzugehen.
6. Watch-Modus und Hot Reload für schnellere Entwicklungsschleifen
Mit dem Flag --watch überwacht Bun alle importierten Dateien eines Skripts und startet den Prozess automatisch neu, sobald sich eine davon ändert, ganz ohne ein zusätzliches Tool wie nodemon zu installieren. Weil die Transpilation ohnehin nativ eingebaut ist, ist der Neustart typischerweise deutlich schneller als bei vergleichbaren Node-basierten Watch-Setups, die zusätzlich ein externes Transpilations-Paket durchlaufen müssen.
Für HTTP-Server bietet Bun mit --hot zusätzlich echtes Hot-Reloading, bei dem laufende Verbindungen erhalten bleiben und nur der geänderte Modulcode ausgetauscht wird, statt den gesamten Prozess neu zu starten. Das reduziert die Downtime während der Entwicklung auf praktisch null und macht iteratives Arbeiten an Server-Code spürbar angenehmer.
# Automatischer Neustart bei Dateiänderung
bun --watch run src/index.ts
# Hot-Reload für HTTP-Server ohne Verbindungsabbruch
bun --hot run src/server.ts
7. Produktions-Builds trotzdem sinnvoll: bun build
Auch wenn Bun TypeScript zur Laufzeit direkt ausführen kann, lohnt sich für Produktionsdeployments meist trotzdem ein expliziter Build-Schritt mit bun build, der den Code bündelt, Minifizierung durchführt und die interne Transpilation zur Laufzeit vermeidet. Ein vorab gebauter Artefakt startet schneller und reduziert die Angriffsfläche, weil der Quellcode nicht im Klartext auf dem Produktionssystem liegt.
Für lokale Entwicklung und schnelle Skripte ist die direkte Ausführung ohne Build dagegen der größte Produktivitätsgewinn, weil jede Codeänderung sofort ohne Wartezeit getestet werden kann, was den klassischen Edit-Compile-Run-Zyklus auf einen reinen Edit-Run-Zyklus verkürzt.
# Entwicklung: direkte Ausführung ohne Build
bun run src/index.ts
# Produktion: explizites Bündeln und Minifizieren
bun build src/index.ts --outdir dist --minify --target bun
8. IDE-Integration und der Typecheck im Editor
Während Bun zur Laufzeit keine Typen prüft, arbeitet die IDE unabhängig davon weiterhin mit dem TypeScript-Language-Server, der Typfehler live im Editor anzeigt, egal ob das Skript später mit Bun oder Node ausgeführt wird. Diese Trennung bedeutet, dass Entwickler in der Praxis meist trotzdem sofortiges Feedback zu Typfehlern bekommen, einfach nicht durch die Runtime selbst, sondern durch die IDE.
Für Teams, die diese Garantie auch außerhalb der IDE brauchen, etwa für Entwickler mit unterschiedlichen Editor-Setups, bleibt ein expliziter tsc --noEmit-Schritt im CI die einzige verlässliche Absicherung, unabhängig davon, welche lokale Umgebung ein Entwickler nutzt.
9. Wann sich Bun für TypeScript-Projekte lohnt
Für schnelle Skripte, lokale Tools und Entwicklungsserver ist die native TypeScript-Ausführung ohne Compile-Schritt ein spürbarer Produktivitätsgewinn, weil der Edit-Run-Zyklus praktisch verzögerungsfrei wird. Für Produktionsdeployments bleibt ein expliziter Build mit bun build meist trotzdem sinnvoll, und ein separater Typecheck-Schritt ist in jedem Fall unverzichtbar, unabhängig davon, ob Bun oder Node als Runtime dient.
Der größte Denkfehler beim Umstieg ist, Ausführbarkeit mit Typkorrektheit zu verwechseln, Bun garantiert nur Ersteres und niemals Letzteres. Wer diese Trennung von Anfang an klar im Kopf behält und tsc konsequent als eigenständigen, separaten CI-Schritt beibehält, profitiert voll von der gewonnenen Geschwindigkeit, ohne dabei die Sicherheit der eigentlichen Typprüfung zu verlieren.
| Merkmal | Bun (bun run) | ts-node/tsx unter Node | tsc-Build plus node |
|---|---|---|---|
| Startzeit | sehr schnell, nativ eingebaut | mittel, zusätzliches Paket | langsam bei erstem Build |
| Typprüfung inklusive | nein, nur Transpilation | nein, nur Transpilation | ja, vollständig |
| Node-API-Kompatibilität | groß, aber nicht vollständig | vollständig, ist Node | vollständig, ist Node |
| Eingebauter Test-Runner | ja, bun test | nein, externes Tool nötig | nein, externes Tool nötig |
| Produktions-Build | optional, bun build | meist eigener Build-Schritt | immer, tsc selbst |
Mironsoft
TypeScript-Migration, Typsicherheit und Team-Onboarding
JavaScript-Codebasis ohne Typsicherheit, aber keine Zeit für eine Rundum-Migration?
Wir migrieren bestehende JavaScript-Projekte schrittweise zu TypeScript, richten strikte Compiler-Einstellungen sauber ein und bringen Teams mit Code-Reviews und Style-Guides auf denselben Typsicherheits-Stand.
Migrations-Fahrplan
Schrittweise JS-zu-TS-Migration ohne Big-Bang-Risiko planen und umsetzen.
Strict-Mode-Einführung
tsconfig.json, ESLint-Regeln und CI-Checks für dauerhafte Typsicherheit aufsetzen.
Team-Onboarding
Entwickler mit Workshops und Code-Reviews in TypeScript-Best-Practices einarbeiten.
10. Zusammenfassung
TypeScript mit Bun
Kernidee
Bun transpiliert TypeScript intern und führt es direkt aus
Wichtigste Grenze
Keine Typprüfung zur Laufzeit, tsc bleibt notwendig
Tests
bun test mit Jest-kompatibler API, ebenfalls ohne Typecheck
Produktion
bun build für gebündelte, schneller startende Artefakte