TypeScript mit Bun: native Ausführung ohne Compile-Schritt
AI generated
type
TypeScript · Bun · Runtime
TypeScript mit Bun
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.

9 Min. Lesezeit Bun Runtime Tooling

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

11. FAQ: TypeScript mit Bun

1Prüft Bun beim Ausführen von TypeScript die Typen?
Nein, Bun entfernt Typannotationen nur syntaktisch und führt den resultierenden JavaScript-Code aus, eine echte Typprüfung findet nicht statt, dafür bleibt ein separater tsc-Lauf nötig.
2Kann ich strict mode in tsconfig.json nutzen, um Bun strenger zu machen?
Nein, Compiler-Optionen wie strict oder noImplicitAny wirken sich nur auf einen separaten tsc-Lauf aus, Bun wertet diese Optionen für die Ausführung nicht aus.
3Brauche ich noch einen Build-Schritt für Produktion?
Meistens ja, bun build erzeugt gebündelte, minifizierte Artefakte, die schneller starten und den Quellcode nicht im Klartext auf dem Produktionssystem hinterlassen.
4Funktionieren bestehende Node-TypeScript-Projekte automatisch unter Bun?
In vielen Fällen ja, weil Bun einen großen Teil der Node-APIs implementiert, es gibt aber Lücken bei selteneren APIs, ein Testlauf unter Bun deckt Kompatibilitätsprobleme früh auf.
5Ist bun test ein vollwertiger Ersatz für Jest?
Für die meisten Standardfälle ja, dank der Jest-kompatiblen API, bei sehr spezifischen Jest-Plugins oder Custom-Matchern kann es aber Lücken geben, die einzelne Anpassungen erfordern.
6Wie schnell ist bun run im Vergleich zu ts-node?
Deutlich schneller, weil die Transpilation nativ in Bun eingebaut ist statt über ein zusätzliches npm-Paket zu laufen, besonders beim Start ist der Unterschied spürbar.
7Zeigt mir die IDE trotzdem Typfehler, wenn ich mit Bun ausführe?
Ja, der TypeScript-Language-Server der IDE arbeitet unabhängig von der Runtime und zeigt Typfehler live im Editor an, unabhängig davon, ob später mit Bun oder Node ausgeführt wird.
8Respektiert Bun Pfad-Aliase aus tsconfig.json?
Ja, paths und baseUrl werden von Bun für die Modulauflösung berücksichtigt, im Gegensatz zu reinen Typprüfungs-Optionen, die keinen Effekt auf die Ausführung haben.
9Sollte ich tsc trotzdem im CI laufen lassen, wenn ich Bun nutze?
Ja, unbedingt, ein separater tsc --noEmit-Schritt bleibt die einzige verlässliche Absicherung gegen Typfehler, unabhängig von der verwendeten Runtime.
10Eignet sich Bun für große Produktions-Backends?
Zunehmend ja, viele Teams setzen Bun produktiv ein, entscheidend ist aber, die Node-API-Kompatibilität für die konkret genutzten Module vorab zu prüfen und einen expliziten Build-Schritt einzuplanen.