Documentation Index
Fetch the complete documentation index at: https://mintlify.com/zhcndoc/bun/llms.txt
Use this file to discover all available pages before exploring further.
Bun includes a fast transpiler that converts TypeScript, JSX, and modern JavaScript to browser-compatible JavaScript. It’s written in Zig and optimized for performance.
Basic Usage
import { Transpiler } from "bun";
const transpiler = new Transpiler({
loader: "tsx",
});
const code = `
const greeting: string = "Hello";
export const App = () => <div>{greeting}</div>;
`;
const output = transpiler.transformSync(code);
console.log(output);
Transpiler Options
Loader
Specify the input format:
const transpiler = new Transpiler({
loader: "tsx", // .tsx files (TypeScript + JSX)
});
// Supported loaders:
// "js" - JavaScript
// "jsx" - JavaScript + JSX
// "ts" - TypeScript
// "tsx" - TypeScript + JSX
Target
Set the output JavaScript version:
const transpiler = new Transpiler({
loader: "ts",
target: "browser", // or "bun", "node"
});
Targets:
"browser" - Modern browsers (ES2020+)
"bun" - Bun runtime (latest features)
"node" - Node.js compatibility
JSX Configuration
const transpiler = new Transpiler({
loader: "tsx",
jsxFactory: "h", // Default: "React.createElement"
jsxFragment: "Fragment", // Default: "React.Fragment"
jsxImportSource: "preact", // For automatic JSX runtime
});
const transpiler = new Transpiler({
loader: "tsx",
jsxFactory: "h",
jsxFragment: "Fragment",
});
// Input:
// <div>Hello</div>
// Output:
h("div", null, "Hello")
Automatic JSX Runtime
const transpiler = new Transpiler({
loader: "tsx",
jsxImportSource: "react",
});
// Input:
// <div>Hello</div>
// Output includes:
// import { jsx } from "react/jsx-runtime";
// jsx("div", { children: "Hello" })
TSConfig
Load TypeScript configuration:
const transpiler = new Transpiler({
loader: "ts",
tsconfig: "./tsconfig.json",
});
Or provide inline:
const transpiler = new Transpiler({
loader: "ts",
tsconfig: {
compilerOptions: {
target: "ES2020",
jsx: "react",
},
},
});
Macros
Enable compile-time macros:
const transpiler = new Transpiler({
loader: "ts",
macro: true,
});
Fastest for small inputs:
const transpiler = new Transpiler({ loader: "ts" });
const code = `const x: number = 42;`;
const output = transpiler.transformSync(code);
console.log(output); // "const x = 42;"
const result = transpiler.transformSync(code, {
sourceMap: "inline", // or "external"
});
console.log(result.code);
console.log(result.map); // Source map object
Scan Imports
Extract import statements:
const code = `
import React from "react";
import { useState } from "react";
import * as utils from "./utils";
`;
const imports = transpiler.scan(code);
console.log(imports);
// [
// { kind: "import-statement", path: "react" },
// { kind: "import-statement", path: "react" },
// { kind: "import-statement", path: "./utils" },
// ]
TypeScript Features
Type Stripping
Types are removed:
const transpiler = new Transpiler({ loader: "ts" });
const input = `
interface User {
name: string;
age: number;
}
function greet(user: User): string {
return \`Hello, \${user.name}\`;
}
`;
const output = transpiler.transformSync(input);
// Types removed, logic preserved
Enums
const input = `
enum Color {
Red,
Green,
Blue,
}
const c = Color.Red;
`;
const output = transpiler.transformSync(input);
// Enum transpiled to object
Decorators
const transpiler = new Transpiler({
loader: "ts",
tsconfig: {
compilerOptions: {
experimentalDecorators: true,
},
},
});
const input = `
@sealed
class MyClass {
@readonly
name: string;
}
`;
const output = transpiler.transformSync(input);
Namespace
const input = `
namespace Utils {
export function log(msg: string) {
console.log(msg);
}
}
`;
const output = transpiler.transformSync(input);
// Namespace transpiled to IIFE
JSX Features
JSX Elements
const transpiler = new Transpiler({ loader: "tsx" });
const input = `
export const Button = ({ text }) => (
<button className="btn" onClick={handleClick}>
{text}
</button>
);
`;
const output = transpiler.transformSync(input);
JSX Fragments
const input = `
const List = () => (
<>
<li>Item 1</li>
<li>Item 2</li>
</>
);
`;
const output = transpiler.transformSync(input);
// <> transpiled to Fragment
JSX Spread
const input = `
const Component = (props) => <div {...props} />;
`;
const output = transpiler.transformSync(input);
Modern JavaScript
Optional Chaining
const input = `
const name = user?.profile?.name;
`;
const output = transpiler.transformSync(input);
// Transpiled for older targets
Nullish Coalescing
const input = `
const value = input ?? defaultValue;
`;
const output = transpiler.transformSync(input);
Class Fields
const input = `
class Counter {
count = 0;
increment = () => {
this.count++;
}
}
`;
const output = transpiler.transformSync(input);
Top-Level Await
const input = `
const data = await fetch(url).then(r => r.json());
export { data };
`;
const output = transpiler.transformSync(input);
// Preserved if target supports it
Source Maps
Inline Source Map
const result = transpiler.transformSync(code, {
sourceMap: "inline",
});
// Source map appended as data URL:
// //# sourceMappingURL=data:application/json;base64,...
External Source Map
const result = transpiler.transformSync(code, {
sourceMap: "external",
});
console.log(result.code); // JavaScript output
console.log(result.map); // Source map object
// Write to file
Bun.write("output.js", result.code);
Bun.write("output.js.map", JSON.stringify(result.map));
Scan for Dependencies
Import Analysis
const code = `
import { foo } from "./foo";
import type { Bar } from "./bar";
const lazy = () => import("./lazy");
require("legacy");
`;
const imports = transpiler.scan(code);
for (const imp of imports) {
console.log(imp.kind, imp.path);
}
// "import-statement" "./foo"
// "import-statement" "./bar"
// "dynamic-import" "./lazy"
// "require-call" "legacy"
Export Analysis
const code = `
export const foo = 1;
export default function bar() {}
export { baz } from "./baz";
`;
const exports = transpiler.scanExports(code);
console.log(exports);
// ["foo", "default", "baz"]
Benchmarks
Bun’s transpiler is extremely fast:
const transpiler = new Transpiler({ loader: "tsx" });
const code = `/* 10,000 lines of TypeScript */`;
const start = performance.now();
for (let i = 0; i < 100; i++) {
transpiler.transformSync(code);
}
const elapsed = performance.now() - start;
console.log(`${elapsed}ms for 100 iterations`);
// Typically 10-50ms
Comparison:
- Bun: ~0.5ms per file
- esbuild: ~1-2ms per file
- tsc: ~50-100ms per file
- Babel: ~100-200ms per file
Optimization Tips
-
Reuse transpiler instance
// Good - one instance
const transpiler = new Transpiler({ loader: "ts" });
for (const file of files) {
transpiler.transformSync(file);
}
// Bad - creates many instances
for (const file of files) {
const t = new Transpiler({ loader: "ts" });
t.transformSync(file);
}
-
Disable source maps when not needed
transpiler.transformSync(code); // Faster
transpiler.transformSync(code, { sourceMap: "inline" }); // Slower
-
Use specific loaders
new Transpiler({ loader: "js" }); // Fastest
new Transpiler({ loader: "ts" }); // Fast
new Transpiler({ loader: "tsx" }); // Slower (parses JSX)
vs TypeScript Compiler (tsc)
- Bun: Type stripping only (no type checking)
- tsc: Full type checking + transpilation
- Speed: Bun is ~100x faster
- Use case: Bun for development, tsc for CI
vs esbuild
- Bun: Built-in, no dependencies
- esbuild: Separate tool
- Speed: Similar (both very fast)
- Features: Bun has tighter integration
vs Babel
- Bun: TypeScript + JSX built-in
- Babel: Requires plugins
- Speed: Bun is ~200x faster
- Flexibility: Babel has more transforms
vs SWC
- Bun: Written in Zig
- SWC: Written in Rust
- Speed: Similar performance
- Integration: Bun has deeper runtime integration
Use Cases
import { Transpiler } from "bun";
import { glob } from "bun";
const transpiler = new Transpiler({ loader: "tsx" });
const files = glob("src/**/*.{ts,tsx}");
for (const file of files) {
const code = await Bun.file(file).text();
const output = transpiler.transformSync(code);
const outPath = file
.replace("src/", "dist/")
.replace(/\.tsx?$/, ".js");
await Bun.write(outPath, output);
}
Hot Module Replacement
const transpiler = new Transpiler({ loader: "tsx" });
const watcher = fs.watch("src", { recursive: true });
for await (const event of watcher) {
if (event.filename?.endsWith(".tsx")) {
const code = await Bun.file(event.filename).text();
const output = transpiler.transformSync(code);
// Send to browser via WebSocket
ws.send({ type: "update", code: output });
}
}
Testing
import { Transpiler } from "bun";
const transpiler = new Transpiler({ loader: "ts" });
// Transform test files on the fly
globalThis.require = (path) => {
const code = Bun.readFileSync(path, "utf8");
const transpiled = transpiler.transformSync(code);
return eval(transpiled);
};
Documentation
const transpiler = new Transpiler({ loader: "ts" });
// Extract code examples from markdown
const examples = extractCodeBlocks(markdown);
for (const example of examples) {
try {
const output = transpiler.transformSync(example.code);
console.log("✓ Example is valid TypeScript");
} catch (err) {
console.error("✗ Example has syntax error:", err.message);
}
}
Advanced Configuration
Custom Defines
const transpiler = new Transpiler({
loader: "ts",
define: {
"process.env.NODE_ENV": '"production"',
DEBUG: "false",
},
});
const input = `
if (DEBUG) {
console.log("Debug mode");
}
`;
const output = transpiler.transformSync(input);
// DEBUG replaced with false
Path Resolution
const transpiler = new Transpiler({
loader: "ts",
tsconfig: {
compilerOptions: {
paths: {
"@/*": ["./src/*"],
"components/*": ["./src/components/*"],
},
},
},
});
External Packages
const transpiler = new Transpiler({
loader: "ts",
external: ["react", "react-dom"],
});
// Imports to external packages are preserved
Error Handling
try {
const output = transpiler.transformSync("invalid typescript!@#$");
} catch (err) {
console.error("Syntax error:");
console.error(err.message);
console.error(`Line ${err.line}, Column ${err.column}`);
}