Skip to main content
Bun provides a collection of utility functions for common tasks like memory management, shell escaping, string operations, and more.

Memory Management

Bun.allocUnsafe()

Allocate uninitialized buffer (fast):
// Allocate 1KB buffer
const buffer = Bun.allocUnsafe(1024);

console.log(buffer.byteLength); // 1024

// Buffer contains random data
console.log(buffer[0]); // Random value
Warning: Data is uninitialized. Use for performance when you’ll immediately write to it.

Bun.shrink()

Shrink buffer to actual size:
const buffer = new Uint8Array(1024);
// Write some data
buffer[0] = 1;
buffer[1] = 2;
buffer[2] = 3;

// Shrink to 3 bytes
const small = Bun.shrink(buffer, 3);
console.log(small.byteLength); // 3

Bun.mmap()

Memory-map a file:
const mapped = Bun.mmap("large-file.bin");

console.log(mapped.byteLength);

// Read data without loading entire file
const view = new Uint8Array(mapped);
console.log(view[0], view[1], view[2]);
Benefits:
  • Zero-copy file access
  • Operating system manages memory
  • Efficient for large files

Shell Utilities

Bun.which()

Find executable in PATH:
const path = Bun.which("node");
console.log(path); // "/usr/local/bin/node"

const git = Bun.which("git");
console.log(git); // "/usr/bin/git"

const missing = Bun.which("nonexistent");
console.log(missing); // null
Cross-platform (works on Windows, macOS, Linux).

Bun.shellEscape()

Escape string for shell:
const filename = "my file.txt";
const escaped = Bun.shellEscape(filename);
console.log(escaped); // "my\\ file.txt"

// Safe to use in shell commands
const cmd = `cat ${escaped}`;
Prevents shell injection:
const userInput = "file; rm -rf /";
const safe = Bun.shellEscape(userInput);
// safe = "file;\\ rm\\ -rf\\ /"

String Utilities

Bun.stringWidth()

Get display width of string:
// ASCII characters
console.log(Bun.stringWidth("hello")); // 5

// Emoji (counts as 2)
console.log(Bun.stringWidth("👋")); // 2

// Chinese characters (2 each)
console.log(Bun.stringWidth("你好")); // 4

// ANSI escape codes (ignored)
console.log(Bun.stringWidth("\x1b[31mred\x1b[0m")); // 3
Useful for:
  • Terminal formatting
  • Table alignment
  • Progress bars

Bun.indexOfLine()

Find line number of byte offset:
const text = `line 1
line 2
line 3`;

// Find line at byte offset 10
const line = Bun.indexOfLine(text, 10);
console.log(line); // 1 (0-indexed)
Useful for:
  • Error reporting
  • Source maps
  • Text editors

Timing

Bun.nanoseconds()

High-resolution timestamp:
const start = Bun.nanoseconds();

// Do some work
for (let i = 0; i < 1000000; i++) {
  Math.sqrt(i);
}

const end = Bun.nanoseconds();
const elapsed = (end - start) / 1_000_000; // Convert to ms

console.log(`Elapsed: ${elapsed.toFixed(3)}ms`);
More precise than Date.now() or performance.now().

Bun.sleepSync()

Synchronous sleep:
console.log("Start");
Bun.sleepSync(1000); // Sleep 1 second
console.log("End");
Warning: Blocks the event loop. Use sparingly. Better alternative (async):
await Bun.sleep(1000); // Non-blocking

Inspection

Bun.inspect()

Format value for display:
const obj = {
  name: "Alice",
  age: 30,
  nested: { value: 42 },
};

const str = Bun.inspect(obj);
console.log(str);
// "{ name: 'Alice', age: 30, nested: { value: 42 } }"
With options:
const str = Bun.inspect(obj, {
  colors: true,      // Enable ANSI colors
  depth: 10,         // Max depth
  sorted: true,      // Sort object keys
});
Like util.inspect() in Node.js but faster.

Bun.inspect.custom

Custom inspection:
class User {
  constructor(public name: string, private password: string) {}
  
  [Bun.inspect.custom]() {
    return `User(${this.name})`;
  }
}

const user = new User("Alice", "secret");
console.log(Bun.inspect(user)); // "User(Alice)"

System Information

Bun.version

Bun version string:
console.log(Bun.version); // "1.0.0"

Bun.revision

Git commit hash:
console.log(Bun.revision); // "abc123def456..."

Bun.env

Environment variables:
console.log(Bun.env.PATH);
console.log(Bun.env.HOME);
console.log(Bun.env.NODE_ENV);

// Set environment variable
Bun.env.MY_VAR = "value";
Prefer process.env for compatibility:
console.log(process.env.PATH);

Bun.main

Entry point file:
console.log(Bun.main); // "/path/to/script.ts"

// Check if file is main module
if (import.meta.path === Bun.main) {
  console.log("This is the entry point");
}

Bun.argv

Command-line arguments:
// bun run script.ts arg1 arg2
console.log(Bun.argv);
// ["/path/to/bun", "/path/to/script.ts", "arg1", "arg2"]
Prefer process.argv for compatibility.

Bun.cwd()

Current working directory:
console.log(Bun.cwd()); // "/path/to/project"
Prefer process.cwd() for compatibility.

Editor Integration

Bun.openInEditor()

Open file in editor:
// Open at specific line
Bun.openInEditor("/path/to/file.ts:42");

// Open at line and column
Bun.openInEditor("/path/to/file.ts:42:10");

// Just open file
Bun.openInEditor("/path/to/file.ts");
Respects $EDITOR environment variable:
export EDITOR="code" # VS Code
export EDITOR="vim"  # Vim
export EDITOR="subl" # Sublime Text

ANSI Colors

Bun.enableANSIColors

Check if colors are enabled:
if (Bun.enableANSIColors) {
  console.log("\x1b[31mRed text\x1b[0m");
} else {
  console.log("Plain text");
}
Colors are enabled when:
  • Running in a TTY
  • NO_COLOR is not set
  • FORCE_COLOR is set

Origin

Bun.origin

Base URL for imports:
console.log(Bun.origin); // "file://"
Used internally for module resolution.

Performance Measurement

High-Resolution Timing

function benchmark(fn: () => void, iterations: number) {
  const start = Bun.nanoseconds();
  
  for (let i = 0; i < iterations; i++) {
    fn();
  }
  
  const end = Bun.nanoseconds();
  const total = (end - start) / 1_000_000; // ms
  const avg = total / iterations;
  
  console.log(`Total: ${total.toFixed(3)}ms`);
  console.log(`Average: ${avg.toFixed(6)}ms`);
}

benchmark(() => JSON.parse('{"x":1}'), 100_000);

Memory Profiling

const before = process.memoryUsage();

// Allocate memory
const buffers = [];
for (let i = 0; i < 1000; i++) {
  buffers.push(Bun.allocUnsafe(1024));
}

const after = process.memoryUsage();

const diff = {
  rss: (after.rss - before.rss) / 1024 / 1024,
  heapUsed: (after.heapUsed - before.heapUsed) / 1024 / 1024,
};

console.log(`RSS: ${diff.rss.toFixed(2)} MB`);
console.log(`Heap: ${diff.heapUsed.toFixed(2)} MB`);

Common Patterns

Safe Command Execution

function safeCommand(cmd: string, args: string[]) {
  const escapedArgs = args.map(arg => Bun.shellEscape(arg));
  return `${cmd} ${escapedArgs.join(" ")}`;
}

const command = safeCommand("grep", ["search term", "my file.txt"]);
console.log(command);
// grep "search\\ term" "my\\ file.txt"

Terminal Table Formatting

function formatTable(rows: string[][]) {
  // Calculate column widths
  const widths = rows[0].map((_, i) =>
    Math.max(...rows.map(row => Bun.stringWidth(row[i] || "")))
  );
  
  // Format rows
  return rows.map(row =>
    row
      .map((cell, i) => cell.padEnd(widths[i]))
      .join(" | ")
  ).join("\n");
}

const table = formatTable([
  ["Name", "Age", "City"],
  ["Alice", "30", "NYC"],
  ["Bob", "25", "LA"],
]);

console.log(table);
// Name  | Age | City
// Alice | 30  | NYC
// Bob   | 25  | LA

Error Location

function reportError(source: string, offset: number, message: string) {
  const line = Bun.indexOfLine(source, offset);
  const lines = source.split("\n");
  const lineContent = lines[line];
  
  console.error(`Error at line ${line + 1}:`);
  console.error(`  ${lineContent}`);
  console.error(`  ${message}`);
}

const code = `function add(a, b) {
  return a + b
}`;

reportError(code, 25, "Missing semicolon");

Memory-Efficient File Processing

async function processLargeFile(path: string) {
  // Memory-map instead of loading entire file
  const mapped = Bun.mmap(path);
  const view = new Uint8Array(mapped);
  
  // Process in chunks
  const chunkSize = 1024 * 1024; // 1MB
  for (let i = 0; i < view.length; i += chunkSize) {
    const chunk = view.subarray(i, i + chunkSize);
    await processChunk(chunk);
  }
}

Best Practices

  1. Prefer standard APIs when available
    // Good - standard
    console.log(process.cwd());
    
    // Less portable
    console.log(Bun.cwd());
    
  2. Use allocUnsafe carefully
    // Good - immediately fill
    const buf = Bun.allocUnsafe(4);
    buf[0] = 1;
    buf[1] = 2;
    buf[2] = 3;
    buf[3] = 4;
    
    // Bad - reading uninitialized memory
    const buf2 = Bun.allocUnsafe(4);
    console.log(buf2[0]); // Random data!
    
  3. Escape user input
    // Good - escaped
    const safe = Bun.shellEscape(userInput);
    const cmd = `ls ${safe}`;
    
    // Bad - injection risk
    const cmd2 = `ls ${userInput}`;
    
  4. Use nanoseconds for benchmarks
    // Good - high precision
    const start = Bun.nanoseconds();
    doWork();
    const elapsed = Bun.nanoseconds() - start;
    
    // Less precise
    const start2 = Date.now();
    doWork();
    const elapsed2 = Date.now() - start2;
    

Platform Differences

Windows

  • Bun.which() searches .exe, .cmd, .bat extensions
  • Bun.shellEscape() uses Windows escaping rules
  • Bun.mmap() uses Windows file mapping APIs

macOS/Linux

  • Bun.which() searches PATH without extensions
  • Bun.shellEscape() uses shell escaping
  • Bun.mmap() uses POSIX mmap()

API Reference

Memory

Bun.allocUnsafe(size: number): Uint8Array
Bun.shrink(buffer: ArrayBufferLike, size: number): ArrayBufferLike
Bun.mmap(path: string): ArrayBuffer

Shell

Bun.which(command: string): string | null
Bun.shellEscape(str: string): string

String

Bun.stringWidth(str: string): number
Bun.indexOfLine(str: string, offset: number): number

Timing

Bun.nanoseconds(): number
Bun.sleepSync(ms: number): void

Inspection

Bun.inspect(value: any, options?: InspectOptions): string

System

Bun.version: string
Bun.revision: string
Bun.main: string
Bun.argv: string[]
Bun.env: Record<string, string>
Bun.cwd(): string
Bun.openInEditor(path: string): void

Build docs developers (and LLMs) love