Skip to main content
Bun natively executes TypeScript files without requiring a separate compilation step. Type annotations are stripped at runtime using Bun’s fast transpiler.

Quick Start

Run TypeScript files directly:
Run TypeScript
bun run app.ts
bun run server.mts
No tsc, no ts-node, no configuration needed.

Features

Zero Config

Works out of the box without tsconfig.json

Fast Transpilation

Written in Zig for maximum performance

Source Maps

Accurate source maps for debugging

Path Mapping

Respects tsconfig paths automatically

How It Works

Bun’s TypeScript transpiler:
  1. Strips type annotations - Removes TypeScript syntax
  2. Preserves runtime behavior - No type checking or validation
  3. Generates source maps - Maps back to original TypeScript
  4. Caches output - Hashes input to avoid re-transpiling
Bun does not perform type checking. Use tsc --noEmit for type validation.

Supported TypeScript Features

Type Annotations

All type annotations are removed:
Type annotations
// Types removed at runtime
function add(a: number, b: number): number {
  return a + b;
}

// Interfaces completely erased
interface User {
  id: number;
  name: string;
  email?: string;
}

// Type aliases removed
type Status = "pending" | "complete";

// Generic types erased
function identity<T>(value: T): T {
  return value;
}

Enums

Enums are compiled to JavaScript objects:
Enums
// Numeric enum
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

// String enum
enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE",
}

// Const enum (inlined)
const enum Status {
  Active = 1,
  Inactive = 0,
}
Output behavior:
  • Regular enums → JavaScript objects
  • Const enums → Inlined values (optimized)

Namespaces

Namespaces are supported but discouraged (use ES modules):
Namespaces
namespace Utils {
  export function log(msg: string) {
    console.log(msg);
  }
}

Utils.log("Hello");

Decorators

Bun supports both experimental and standard decorators:
Decorators
// Experimental decorators (legacy)
function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Handler {}

// Standard decorators (TC39 Stage 3)
function log(target: any, context: ClassMethodDecoratorContext) {
  return function (this: any, ...args: any[]) {
    console.log(`Calling ${String(context.name)}`);
    return target.call(this, ...args);
  };
}

class Service {
  @log
  execute() {}
}
Configuration:
tsconfig.json
{
  "compilerOptions": {
    // For legacy decorators
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
Implementation: src/runtime.zig:203-204

Using Declarations

Explicit resource management (TC39 Stage 3):
Using declarations
// Automatic cleanup with 'using'
using file = await openFile("data.txt");
// file.close() called automatically

// Async cleanup with 'await using'
await using db = await connectDB();
// await db.disconnect() called automatically
Compiles to try/finally blocks with resource disposal.

Import/Export Extensions

Bun supports TypeScript import extensions:
Import extensions
// Import with .ts extension
import { add } from "./math.ts";

// Import type only
import type { User } from "./types.ts";

// Import with assertion
import data from "./data.json" assert { type: "json" };

tsconfig.json Support

Bun respects tsconfig.json configuration:

Path Mapping

tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "~/*": ["./*"]
    }
  }
}
Using path aliases
import { Button } from "@components/Button";
import { config } from "@/config";
import { helper } from "~/utils/helper";
Implementation: src/resolver/resolver.zig

Compiler Options

Bun honors these tsconfig.json options:
  • moduleResolution - “node”, “bundler”, “node16”, “nodenext”
  • baseUrl - Base directory for module resolution
  • paths - Path mapping for imports
  • types - Type declaration packages to include
  • typeRoots - Directories containing type definitions
  • jsx - “react”, “react-jsx”, “react-jsxdev”, “preserve”
  • jsxFactory - JSX factory function (default: React.createElement)
  • jsxFragmentFactory - Fragment factory (default: React.Fragment)
  • jsxImportSource - Import source for automatic runtime
  • experimentalDecorators - Enable legacy decorators
  • emitDecoratorMetadata - Emit design-time metadata
  • useDefineForClassFields - Class field initialization
  • importsNotUsedAsValues - Preserve/remove imports
  • esModuleInterop - Enable default import interop
  • allowSyntheticDefaultImports - Allow default imports from CommonJS
  • resolveJsonModule - Allow importing .json files
Bun ignores type-checking options (strict, noImplicitAny, etc.) as it doesn’t perform type checking.

Runtime Transpiler Cache

Bun caches transpiled TypeScript to avoid repeated parsing: Cache location:
  • Linux: ~/.bun/install/cache/
  • macOS: ~/Library/Caches/Bun/
  • Windows: %LOCALAPPDATA%\Bun\Cache\
Cache invalidation:
  • File content changes (hash-based)
  • tsconfig.json modifications
  • Bun version updates
Implementation: src/runtime.zig:210 - Runtime transpiler cache

Disable Cache

Disable cache
export BUN_RUNTIME_TRANSPILER_CACHE_PATH=0
bun run app.ts

Type Checking

Bun focuses on execution, not type checking. For type validation:

Using TypeScript Compiler

Type checking
# Check types without emitting files
bun x tsc --noEmit

# With watch mode
bun x tsc --noEmit --watch

Package.json Scripts

package.json
{
  "scripts": {
    "dev": "bun run src/index.ts",
    "typecheck": "tsc --noEmit",
    "check": "bun run typecheck && bun run dev"
  }
}

IDE Integration

Recommended setup:
  1. VS Code - Install TypeScript extension
  2. Configure workspace:
    .vscode/settings.json
    {
      "typescript.tsdk": "node_modules/typescript/lib",
      "typescript.enablePromptUseWorkspaceTsdk": true
    }
    

CommonJS & ESM Interop

Bun seamlessly handles TypeScript with both module systems:

ES Modules (.ts, .mts)

ESM TypeScript
// app.ts - ESM by default
import { readFile } from "node:fs/promises";

export async function loadData(path: string): Promise<string> {
  return await readFile(path, "utf-8");
}

CommonJS (.cts)

CommonJS TypeScript
// utils.cts - Explicit CommonJS
import fs = require("node:fs");

export = {
  readSync(path: string): string {
    return fs.readFileSync(path, "utf-8");
  },
};

Type Imports

Type-only imports
// Only imports types (removed at runtime)
import type { User, Post } from "./types";

// Import value and type separately
import { type Config, loadConfig } from "./config";

Declaration Files (.d.ts)

Bun recognizes TypeScript declaration files:
Declaration files
// types.d.ts
declare module "*.png" {
  const value: string;
  export default value;
}

declare global {
  const BUILD_ID: string;
}

// Augment existing module
declare module "bun" {
  interface Env {
    DATABASE_URL: string;
  }
}

Debugging TypeScript

Bun generates source maps for accurate debugging:

VS Code Launch Config

.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug TypeScript",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "bun",
      "runtimeArgs": ["run", "--inspect"],
      "program": "${workspaceFolder}/src/index.ts",
      "console": "integratedTerminal",
      "skipFiles": ["<node_internals>/**"]
    }
  ]
}
See Debugger documentation for more details.

Performance

Bun’s TypeScript transpiler is significantly faster than tsc or ts-node:
  • Written in Zig: Native code, no JavaScript overhead
  • Parallel parsing: Multi-threaded for large projects
  • Lazy transpilation: Only transpiles imported files
  • Efficient caching: Hash-based cache invalidation
Benchmark comparison (transpiling 10,000 TypeScript files):
ToolTime
Bun~0.5s
esbuild~2s
tsc~15s
ts-node~30s
Benchmarks approximate, actual performance depends on code complexity.

Implementation Details

TypeScript transpilation implementation:
  • Parser: src/js_parser.zig - Parses TypeScript AST
  • Printer: src/js_printer.zig - Generates JavaScript
  • Transpiler: src/transpiler.zig - Orchestrates parsing/printing
  • Runtime features: src/runtime.zig:144-327 - Feature flags and configuration

Limitations

Bun’s TypeScript support has some limitations:
  • No type checking (use tsc --noEmit)
  • No .d.ts generation (use tsc --emitDeclarationOnly)
  • Some advanced features may not work identically to tsc

Troubleshooting

Module Resolution Issues

Check resolution
# Debug module resolution
BUN_DEBUG_QUIET_LOGS=0 bun run app.ts 2>&1 | grep -i resolve

Path Mapping Not Working

Ensure tsconfig.json is in the project root:
.
├── tsconfig.json
├── package.json  
└── src/
    └── index.ts

Build docs developers (and LLMs) love