bun-types
Version:
Type definitions and documentation for Bun, an incredibly fast JavaScript runtime
1,415 lines (1,314 loc) โข 324 kB
TypeScript
/**
* Bun.js runtime APIs
*
* @example
*
* ```js
* import {file} from 'bun';
*
* // Log the file to the console
* const input = await file('/path/to/file.txt').text();
* console.log(input);
* ```
*
* This module aliases `globalThis.Bun`.
*/
declare module "bun" {
type PathLike = string | NodeJS.TypedArray | ArrayBufferLike | URL;
type ArrayBufferView<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> =
| NodeJS.TypedArray<TArrayBuffer>
| DataView<TArrayBuffer>;
type BufferSource = NodeJS.TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike> | ArrayBufferLike;
type StringOrBuffer = string | NodeJS.TypedArray | ArrayBufferLike;
type XMLHttpRequestBodyInit = Blob | BufferSource | FormData | URLSearchParams | string;
type ReadableStreamController<T> = ReadableStreamDefaultController<T>;
type ReadableStreamDefaultReadResult<T> =
| ReadableStreamDefaultReadValueResult<T>
| ReadableStreamDefaultReadDoneResult;
type ReadableStreamReader<T> = ReadableStreamDefaultReader<T>;
type Transferable = ArrayBuffer | MessagePort;
type MessageEventSource = Bun.__internal.UseLibDomIfAvailable<"MessageEventSource", undefined>;
type Encoding = "utf-8" | "windows-1252" | "utf-16";
type UncaughtExceptionOrigin = "uncaughtException" | "unhandledRejection";
type MultipleResolveType = "resolve" | "reject";
type BeforeExitListener = (code: number) => void;
type DisconnectListener = () => void;
type ExitListener = (code: number) => void;
type RejectionHandledListener = (promise: Promise<unknown>) => void;
type FormDataEntryValue = File | string;
type WarningListener = (warning: Error) => void;
type MessageListener = (message: unknown, sendHandle: unknown) => void;
type SignalsListener = (signal: NodeJS.Signals) => void;
type BlobPart = string | Blob | BufferSource;
type TimerHandler = (...args: any[]) => void;
type DOMHighResTimeStamp = number;
type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
type BlobOrStringOrBuffer = string | NodeJS.TypedArray | ArrayBufferLike | Blob;
type MaybePromise<T> = T | Promise<T>;
namespace __internal {
type LibDomIsLoaded = typeof globalThis extends { onabort: any } ? true : false;
/**
* Helper type for avoiding conflicts in types.
*
* Uses the lib.dom.d.ts definition if it exists, otherwise defines it locally.
*
* This is to avoid type conflicts between lib.dom.d.ts and \@types/bun.
*
* Unfortunately some symbols cannot be defined when both Bun types and lib.dom.d.ts types are loaded,
* and since we can't redeclare the symbol in a way that satisfies both, we need to fallback
* to the type that lib.dom.d.ts provides.
*/
type UseLibDomIfAvailable<GlobalThisKeyName extends PropertyKey, Otherwise> =
// `onabort` is defined in lib.dom.d.ts, so we can check to see if lib dom is loaded by checking if `onabort` is defined
LibDomIsLoaded extends true
? typeof globalThis extends { [K in GlobalThisKeyName]: infer T } // if it is loaded, infer it from `globalThis` and use that value
? T
: Otherwise // Not defined in lib dom (or anywhere else), so no conflict. We can safely use our own definition
: Otherwise; // Lib dom not loaded anyway, so no conflict. We can safely use our own definition
/**
* Like Omit, but correctly distributes over unions. Most useful for removing
* properties from union options objects, like {@link Bun.SQL.Options}
*
* @example
* ```ts
* type X = Bun.DistributedOmit<{type?: 'a', url?: string} | {type?: 'b', flag?: boolean}, "url">
* // `{type?: 'a'} | {type?: 'b', flag?: boolean}` (Omit applied to each union item instead of entire type)
*
* type X = Omit<{type?: 'a', url?: string} | {type?: 'b', flag?: boolean}, "url">;
* // `{type?: "a" | "b" | undefined}` (Missing `flag` property and no longer a union)
* ```
*/
type DistributedOmit<T, K extends PropertyKey> = T extends T ? Omit<T, K> : never;
type KeysInBoth<A, B> = Extract<keyof A, keyof B>;
type MergeInner<A, B> = Omit<A, KeysInBoth<A, B>> &
Omit<B, KeysInBoth<A, B>> & {
[Key in KeysInBoth<A, B>]: A[Key] | B[Key];
};
type Merge<A, B> = MergeInner<A, B> & MergeInner<B, A>;
type DistributedMerge<T, Else = T> = T extends T ? Merge<T, Exclude<Else, T>> : never;
type Without<A, B> = A & {
[Key in Exclude<keyof B, keyof A>]?: never;
};
type XOR<A, B> = Without<A, B> | Without<B, A>;
}
interface ErrorEventInit extends EventInit {
colno?: number;
error?: any;
filename?: string;
lineno?: number;
message?: string;
}
interface CloseEventInit extends EventInit {
code?: number;
reason?: string;
wasClean?: boolean;
}
interface MessageEventInit<T = any> extends EventInit {
data?: T;
lastEventId?: string;
origin?: string;
source?: Bun.MessageEventSource | null;
}
interface EventInit {
bubbles?: boolean;
cancelable?: boolean;
composed?: boolean;
}
interface EventListenerOptions {
capture?: boolean;
}
interface CustomEventInit<T = any> extends Bun.EventInit {
detail?: T;
}
/** A message received by a target object. */
interface BunMessageEvent<T = any> extends Event {
/** Returns the data of the message. */
readonly data: T;
/** Returns the last event ID string, for server-sent events. */
readonly lastEventId: string;
/** Returns the origin of the message, for server-sent events and cross-document messaging. */
readonly origin: string;
/** Returns the MessagePort array sent with the message, for cross-document messaging and channel messaging. */
readonly ports: readonly MessagePort[]; // ReadonlyArray<typeof import("worker_threads").MessagePort["prototype"]>;
readonly source: Bun.MessageEventSource | null;
}
type MessageEvent<T = any> = Bun.__internal.UseLibDomIfAvailable<"MessageEvent", BunMessageEvent<T>>;
interface ReadableStreamDefaultReadManyResult<T> {
done: boolean;
/** Number of bytes */
size: number;
value: T[];
}
interface EventSourceEventMap {
error: Event;
message: MessageEvent;
open: Event;
}
interface AddEventListenerOptions extends EventListenerOptions {
/** When `true`, the listener is automatically removed when it is first invoked. Default: `false`. */
once?: boolean;
/** When `true`, serves as a hint that the listener will not call the `Event` object's `preventDefault()` method. Default: false. */
passive?: boolean;
signal?: AbortSignal;
}
interface EventListener {
(evt: Event): void;
}
interface EventListenerObject {
handleEvent(object: Event): void;
}
interface FetchEvent extends Event {
readonly request: Request;
readonly url: string;
waitUntil(promise: Promise<any>): void;
respondWith(response: Response | Promise<Response>): void;
}
interface EventMap {
fetch: FetchEvent;
message: MessageEvent;
messageerror: MessageEvent;
// exit: Event;
}
interface StructuredSerializeOptions {
transfer?: Bun.Transferable[];
}
interface EventSource extends EventTarget {
new (url: string | URL, eventSourceInitDict?: EventSourceInit): EventSource;
onerror: ((this: EventSource, ev: Event) => any) | null;
onmessage: ((this: EventSource, ev: MessageEvent) => any) | null;
onopen: ((this: EventSource, ev: Event) => any) | null;
/** Returns the state of this EventSource object's connection. It can have the values described below. */
readonly readyState: number;
/** Returns the URL providing the event stream. */
readonly url: string;
/** Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.
*
* Not supported in Bun
*/
readonly withCredentials: boolean;
/** Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED. */
close(): void;
readonly CLOSED: 2;
readonly CONNECTING: 0;
readonly OPEN: 1;
addEventListener<K extends keyof EventSourceEventMap>(
type: K,
listener: (this: EventSource, ev: EventSourceEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
addEventListener(
type: string,
listener: (this: EventSource, event: MessageEvent) => any,
options?: boolean | AddEventListenerOptions,
): void;
addEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
removeEventListener<K extends keyof EventSourceEventMap>(
type: K,
listener: (this: EventSource, ev: EventSourceEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
removeEventListener(
type: string,
listener: (this: EventSource, event: MessageEvent) => any,
options?: boolean | EventListenerOptions,
): void;
removeEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
/**
* Keep the event loop alive while connection is open or reconnecting
*
* Not available in browsers
*/
ref(): void;
/**
* Do not keep the event loop alive while connection is open or reconnecting
*
* Not available in browsers
*/
unref(): void;
}
interface TransformerFlushCallback<O> {
(controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;
}
interface TransformerStartCallback<O> {
(controller: TransformStreamDefaultController<O>): any;
}
interface TransformerTransformCallback<I, O> {
(chunk: I, controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;
}
interface UnderlyingSinkAbortCallback {
(reason?: any): void | PromiseLike<void>;
}
interface UnderlyingSinkCloseCallback {
(): void | PromiseLike<void>;
}
interface UnderlyingSinkStartCallback {
(controller: WritableStreamDefaultController): any;
}
interface UnderlyingSinkWriteCallback<W> {
(chunk: W, controller: WritableStreamDefaultController): void | PromiseLike<void>;
}
interface UnderlyingSourceCancelCallback {
(reason?: any): void | PromiseLike<void>;
}
interface UnderlyingSink<W = any> {
abort?: UnderlyingSinkAbortCallback;
close?: UnderlyingSinkCloseCallback;
start?: UnderlyingSinkStartCallback;
type?: undefined | "default" | "bytes";
write?: UnderlyingSinkWriteCallback<W>;
}
interface UnderlyingSource<R = any> {
cancel?: UnderlyingSourceCancelCallback;
pull?: UnderlyingSourcePullCallback<R>;
start?: UnderlyingSourceStartCallback<R>;
/**
* Mode "bytes" is not currently supported.
*/
type?: undefined;
}
interface DirectUnderlyingSource<R = any> {
cancel?: UnderlyingSourceCancelCallback;
pull: (controller: ReadableStreamDirectController) => void | PromiseLike<void>;
type: "direct";
}
interface UnderlyingSourcePullCallback<R> {
(controller: ReadableStreamController<R>): void | PromiseLike<void>;
}
interface UnderlyingSourceStartCallback<R> {
(controller: ReadableStreamController<R>): any;
}
interface GenericTransformStream {
readonly readable: ReadableStream;
readonly writable: WritableStream;
}
interface AbstractWorkerEventMap {
error: ErrorEvent;
}
interface WorkerEventMap extends AbstractWorkerEventMap {
message: MessageEvent;
messageerror: MessageEvent;
close: CloseEvent;
open: Event;
}
type WorkerType = "classic" | "module";
interface AbstractWorker {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/error_event) */
onerror: ((this: AbstractWorker, ev: ErrorEvent) => any) | null;
addEventListener<K extends keyof AbstractWorkerEventMap>(
type: K,
listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
addEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
removeEventListener<K extends keyof AbstractWorkerEventMap>(
type: K,
listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
removeEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
}
/**
* Bun's Web Worker constructor supports some extra options on top of the API browsers have.
*/
interface WorkerOptions {
/**
* A string specifying an identifying name for the DedicatedWorkerGlobalScope representing the scope of
* the worker, which is mainly useful for debugging purposes.
*/
name?: string;
/**
* Use less memory, but make the worker slower.
*
* Internally, this sets the heap size configuration in JavaScriptCore to be
* the small heap instead of the large heap.
*/
smol?: boolean;
/**
* When `true`, the worker will keep the parent thread alive until the worker is terminated or `unref`'d.
* When `false`, the worker will not keep the parent thread alive.
*
* By default, this is `false`.
*/
ref?: boolean;
/**
* In Bun, this does nothing.
*/
type?: Bun.WorkerType | undefined;
/**
* List of arguments which would be stringified and appended to
* `Bun.argv` / `process.argv` in the worker. This is mostly similar to the `data`
* but the values will be available on the global `Bun.argv` as if they
* were passed as CLI options to the script.
*/
argv?: any[] | undefined;
/** If `true` and the first argument is a string, interpret the first argument to the constructor as a script that is executed once the worker is online. */
// eval?: boolean | undefined;
/**
* If set, specifies the initial value of process.env inside the Worker thread. As a special value, worker.SHARE_ENV may be used to specify that the parent thread and the child thread should share their environment variables; in that case, changes to one thread's process.env object affect the other thread as well. Default: process.env.
*/
env?: Record<string, string> | (typeof import("node:worker_threads"))["SHARE_ENV"] | undefined;
/**
* In Bun, this does nothing.
*/
credentials?: import("undici-types").RequestCredentials | undefined;
/**
* @default true
*/
// trackUnmanagedFds?: boolean;
// resourceLimits?: import("worker_threads").ResourceLimits;
/**
* An array of module specifiers to preload in the worker.
*
* These modules load before the worker's entry point is executed.
*
* Equivalent to passing the `--preload` CLI argument, but only for this Worker.
*/
preload?: string[] | string | undefined;
}
interface Worker extends EventTarget, AbstractWorker {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/message_event) */
onmessage: ((this: Worker, ev: MessageEvent) => any) | null;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/messageerror_event) */
onmessageerror: ((this: Worker, ev: MessageEvent) => any) | null;
/**
* Clones message and transmits it to worker's global environment. transfer can be passed as a list of objects that are to be transferred rather than cloned.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/postMessage)
*/
postMessage(message: any, transfer: Transferable[]): void;
postMessage(message: any, options?: StructuredSerializeOptions): void;
/**
* Aborts worker's associated global environment.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/terminate)
*/
terminate(): void;
addEventListener<K extends keyof WorkerEventMap>(
type: K,
listener: (this: Worker, ev: WorkerEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
addEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
removeEventListener<K extends keyof WorkerEventMap>(
type: K,
listener: (this: Worker, ev: WorkerEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
removeEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
/**
* Opposite of `unref()`, calling `ref()` on a previously `unref()`ed worker does _not_ let the program exit if it's the only active handle left (the default
* behavior). If the worker is `ref()`ed, calling `ref()` again has
* no effect.
* @since v10.5.0
*/
ref(): void;
/**
* Calling `unref()` on a worker allows the thread to exit if this is the only
* active handle in the event system. If the worker is already `unref()`ed calling`unref()` again has no effect.
* @since v10.5.0
*/
unref(): void;
/**
* An integer identifier for the referenced thread. Inside the worker thread,
* it is available as `require('node:worker_threads').threadId`.
* This value is unique for each `Worker` instance inside a single process.
* @since v10.5.0
*/
threadId: number;
}
interface Env {
NODE_ENV?: string;
/**
* Can be used to change the default timezone at runtime
*/
TZ?: string;
}
/**
* The environment variables of the process
*
* Defaults to `process.env` as it was when the current Bun process launched.
*
* Changes to `process.env` at runtime won't automatically be reflected in the default value. For that, you can pass `process.env` explicitly.
*/
const env: Env & NodeJS.ProcessEnv & ImportMetaEnv;
/**
* The raw arguments passed to the process, including flags passed to Bun. If you want to easily read flags passed to your script, consider using `process.argv` instead.
*/
const argv: string[];
interface WhichOptions {
/**
* Overrides the PATH environment variable
*/
PATH?: string;
/**
* When given a relative path, use this path to join it.
*/
cwd?: string;
}
/**
* Find the path to an executable, similar to typing which in your terminal. Reads the `PATH` environment variable unless overridden with `options.PATH`.
*
* @category Utilities
*
* @param command The name of the executable or script to find
* @param options Options for the search
*/
function which(command: string, options?: WhichOptions): string | null;
interface StringWidthOptions {
/**
* If `true`, count ANSI escape codes as part of the string width. If `false`, ANSI escape codes are ignored when calculating the string width.
*
* @default false
*/
countAnsiEscapeCodes?: boolean;
/**
* When it's ambiugous and `true`, count emoji as 1 characters wide. If `false`, emoji are counted as 2 character wide.
*
* @default true
*/
ambiguousIsNarrow?: boolean;
}
/**
* Get the column count of a string as it would be displayed in a terminal.
* Supports ANSI escape codes, emoji, and wide characters.
*
* This is useful for:
* - Aligning text in a terminal
* - Quickly checking if a string contains ANSI escape codes
* - Measuring the width of a string in a terminal
*
* This API is designed to match the popular "string-width" package, so that
* existing code can be easily ported to Bun and vice versa.
*
* @returns The width of the string in columns
*
* @example
* ```ts
* import { stringWidth } from "bun";
*
* console.log(stringWidth("abc")); // 3
* console.log(stringWidth("๐ฉโ๐ฉโ๐งโ๐ฆ")); // 1
* console.log(stringWidth("\u001b[31mhello\u001b[39m")); // 5
* console.log(stringWidth("\u001b[31mhello\u001b[39m", { countAnsiEscapeCodes: false })); // 5
* console.log(stringWidth("\u001b[31mhello\u001b[39m", { countAnsiEscapeCodes: true })); // 13
* ```
*/
function stringWidth(
/**
* The string to measure
*/
input: string,
options?: StringWidthOptions,
): number;
/**
* Remove ANSI escape codes from a string.
*
* @category Utilities
*
* @param input The string to remove ANSI escape codes from.
* @returns The string with ANSI escape codes removed.
*
* @example
* ```ts
* import { stripANSI } from "bun";
*
* console.log(stripANSI("\u001b[31mhello\u001b[39m")); // "hello"
* ```
*/
function stripANSI(input: string): string;
interface SliceAnsiOptions {
/**
* If set, and content was cut at either edge of the requested range,
* insert this string at the cut edge(s). The ellipsis is counted against
* the visible-width budget and is emitted *inside* any active SGR styles
* (color, bold, etc.) so it inherits them, but *outside* any active OSC 8
* hyperlink.
*
* This turns `sliceAnsi` into a drop-in `cli-truncate` replacement:
* - truncate-end: `sliceAnsi(str, 0, max, { ellipsis: "\u2026" })`
* - truncate-start: `sliceAnsi(str, -max, undefined, { ellipsis: "\u2026" })`
*/
ellipsis?: string;
/**
* Count characters with East Asian Width "Ambiguous" as 1 column (narrow)
* instead of 2 (wide). Affects Greek, Cyrillic, some symbols, etc. that
* render wide in CJK-encoded terminals but narrow in Western ones.
*
* Matches the option of the same name in {@link stringWidth} and
* {@link wrapAnsi}.
*
* @default true
*/
ambiguousIsNarrow?: boolean;
}
/**
* Slice a string by visible column width, preserving ANSI escape codes.
*
* Like `String.prototype.slice`, but indices are terminal column widths
* (accounting for wide CJK characters, emoji grapheme clusters, and
* zero-width joiners), and ANSI escape sequences (SGR colors, OSC 8
* hyperlinks, etc.) are preserved and correctly re-opened/closed at the
* slice boundaries.
*
* @category Utilities
*
* @param input The string to slice
* @param start Starting column (default 0). Negative counts from end.
* @param end Ending column, exclusive (default end of string). Negative counts from end.
* @param options Optional behavior flags (e.g. `ellipsis` for truncation)
* @returns The sliced string with ANSI codes intact
*
* @example
* ```ts
* import { sliceAnsi } from "bun";
*
* // Plain slice (replaces the `slice-ansi` npm package)
* sliceAnsi("hello", 1, 4); // "ell"
* sliceAnsi("\u001b[31mhello\u001b[39m", 1, 4); // "\u001b[31mell\u001b[39m"
* sliceAnsi("\u5b89\u5b81\u54c8", 0, 4); // "\u5b89\u5b81" (CJK: width 2 each)
*
* // Truncation (replaces the `cli-truncate` npm package)
* sliceAnsi("unicorn", 0, 4, "\u2026"); // "uni\u2026"
* sliceAnsi("unicorn", -4, undefined, "\u2026"); // "\u2026orn"
* ```
*/
function sliceAnsi(
input: string,
start?: number,
end?: number,
/**
* Shorthand for common options (avoids `{}` allocation):
* - `string` โ ellipsis (equivalent to `{ ellipsis: string }`)
* - `boolean` โ ambiguousIsNarrow (equivalent to `{ ambiguousIsNarrow: boolean }`)
* - `SliceAnsiOptions` โ full options object
*/
options?: string | boolean | SliceAnsiOptions,
/**
* ambiguousIsNarrow as a positional arg, usable when the 4th arg is an
* ellipsis string (or `undefined`). Lets you pass both options without
* an object: `sliceAnsi(s, 0, n, "\u2026", false)`.
*/
ambiguousIsNarrow?: boolean,
): string;
interface WrapAnsiOptions {
/**
* If `true`, break words in the middle if they don't fit on a line.
* If `false`, only break at word boundaries.
*
* @default false
*/
hard?: boolean;
/**
* If `true`, wrap at word boundaries when possible.
* If `false`, don't perform word wrapping (only wrap at explicit newlines).
*
* @default true
*/
wordWrap?: boolean;
/**
* If `true`, trim leading and trailing whitespace from each line.
* If `false`, preserve whitespace.
*
* @default true
*/
trim?: boolean;
/**
* When it's ambiguous and `true`, count ambiguous width characters as 1 character wide.
* If `false`, count them as 2 characters wide.
*
* @default true
*/
ambiguousIsNarrow?: boolean;
}
/**
* Wrap a string to fit within the specified column width, preserving ANSI escape codes.
*
* This function is designed to be compatible with the popular "wrap-ansi" NPM package.
*
* Features:
* - Preserves ANSI escape codes (colors, styles) across line breaks
* - Supports SGR codes (colors, bold, italic, etc.) and OSC 8 hyperlinks
* - Respects Unicode display widths (full-width characters, emoji)
* - Word wrapping at word boundaries (configurable)
*
* @category Utilities
*
* @param input The string to wrap
* @param columns The maximum column width
* @param options Wrapping options
* @returns The wrapped string
*
* @example
* ```ts
* import { wrapAnsi } from "bun";
*
* console.log(wrapAnsi("hello world", 5));
* // Output:
* // hello
* // world
*
* // Preserves ANSI colors across line breaks
* console.log(wrapAnsi("\u001b[31mhello world\u001b[0m", 5));
* // Output:
* // \u001b[31mhello\u001b[0m
* // \u001b[31mworld\u001b[0m
*
* // Hard wrap long words
* console.log(wrapAnsi("abcdefghij", 3, { hard: true }));
* // Output:
* // abc
* // def
* // ghi
* // j
* ```
*/
function wrapAnsi(
/**
* The string to wrap
*/
input: string,
/**
* The maximum column width
*/
columns: number,
/**
* Wrapping options
*/
options?: WrapAnsiOptions,
): string;
/**
* TOML related APIs
*/
namespace TOML {
/**
* Parse a TOML string into a JavaScript object.
*
* @category Utilities
*
* @param input The TOML string to parse
* @returns A JavaScript object
*/
export function parse(input: string): object;
}
/**
* JSONC related APIs
*/
namespace JSONC {
/**
* Parse a JSONC (JSON with Comments) string into a JavaScript value.
*
* Supports both single-line (`//`) and block comments (`/* ... *\/`), as well as
* trailing commas in objects and arrays.
*
* @category Utilities
*
* @param input The JSONC string to parse
* @returns A JavaScript value
*
* @example
* ```js
* const result = Bun.JSONC.parse(`{
* // This is a comment
* "name": "my-app",
* "version": "1.0.0", // trailing comma is allowed
* }`);
* ```
*/
export function parse(input: string): unknown;
}
/**
* JSONL (JSON Lines) related APIs.
*
* Each line in the input is expected to be a valid JSON value separated by newlines.
*/
namespace JSONL {
/**
* The result of `Bun.JSONL.parseChunk`.
*/
interface ParseChunkResult {
/** The successfully parsed JSON values. */
values: unknown[];
/** How far into the input was consumed. When the input is a string, this is a character offset. When the input is a `TypedArray`, this is a byte offset. Use `input.slice(read)` or `input.subarray(read)` to get the unconsumed remainder. */
read: number;
/** `true` if all input was consumed successfully. `false` if the input ends with an incomplete value or a parse error occurred. */
done: boolean;
/** A `SyntaxError` if a parse error occurred, otherwise `null`. Values parsed before the error are still available in `values`. */
error: SyntaxError | null;
}
/**
* Parse a JSONL (JSON Lines) string into an array of JavaScript values.
*
* If a parse error occurs and no values were successfully parsed, throws
* a `SyntaxError`. If values were parsed before the error, returns the
* successfully parsed values without throwing.
*
* Incomplete trailing values (e.g. from a partial chunk) are silently
* ignored and not included in the result.
*
* When a `TypedArray` is passed, the bytes are parsed directly without
* copying if the content is ASCII.
*
* @param input The JSONL string or typed array to parse
* @returns An array of parsed values
* @throws {SyntaxError} If the input starts with invalid JSON and no values could be parsed
*
* @example
* ```js
* const items = Bun.JSONL.parse('{"a":1}\n{"b":2}\n');
* // [{ a: 1 }, { b: 2 }]
*
* // From a Uint8Array (zero-copy for ASCII):
* const buf = new TextEncoder().encode('{"a":1}\n{"b":2}\n');
* const items = Bun.JSONL.parse(buf);
* // [{ a: 1 }, { b: 2 }]
*
* // Partial results on error after valid values:
* const partial = Bun.JSONL.parse('{"a":1}\n{bad}\n');
* // [{ a: 1 }]
*
* // Throws when no valid values precede the error:
* Bun.JSONL.parse('{bad}\n'); // throws SyntaxError
* ```
*/
export function parse(input: string | NodeJS.TypedArray | DataView<ArrayBuffer> | ArrayBufferLike): unknown[];
/**
* Parse a JSONL chunk, designed for streaming use.
*
* Never throws on parse errors. Instead, returns whatever values were
* successfully parsed along with an `error` property containing the
* `SyntaxError` (or `null` on success). Use `read` to determine how
* much input was consumed and `done` to check if all input was parsed.
*
* When a `TypedArray` is passed, the bytes are parsed directly without
* copying if the content is ASCII. Optional `start` and `end` parameters
* select a window of the input without copying. For typed arrays these
* are byte offsets and `read` will be a byte offset into the original
* typed array. For strings these are character offsets and `read` will
* be a character offset into the original string.
*
* @param input The JSONL string or typed array to parse
* @param start Offset to start parsing from (bytes for typed arrays, characters for strings, default: 0)
* @param end Offset to stop parsing at (bytes for typed arrays, characters for strings, default: input length)
* @returns An object with `values`, `read`, `done`, and `error` properties
*
* @example
* ```js
* let buffer = new Uint8Array(0);
* for await (const chunk of stream) {
* buffer = Buffer.concat([buffer, chunk]);
* const { values, read, error } = Bun.JSONL.parseChunk(buffer);
* if (error) throw error;
* for (const value of values) handle(value);
* buffer = buffer.subarray(read);
* }
* ```
*/
export function parseChunk(
input: string | NodeJS.TypedArray | DataView<ArrayBuffer> | ArrayBufferLike,
start?: number,
end?: number,
): ParseChunkResult;
}
/**
* YAML related APIs
*/
namespace YAML {
/**
* Parse a YAML string into a JavaScript value
*
* @category Utilities
*
* @param input The YAML string to parse
* @returns A JavaScript value
*
* @example
* ```ts
* import { YAML } from "bun";
*
* console.log(YAML.parse("123")) // 123
* console.log(YAML.parse("null")) // null
* console.log(YAML.parse("false")) // false
* console.log(YAML.parse("abc")) // "abc"
* console.log(YAML.parse("- abc")) // [ "abc" ]
* console.log(YAML.parse("abc: def")) // { "abc": "def" }
* ```
*/
export function parse(input: string): unknown;
/**
* Convert a JavaScript value into a YAML string. Strings are double quoted if they contain keywords, non-printable or
* escaped characters, or if a YAML parser would parse them as numbers. Anchors and aliases are inferred from objects, allowing cycles.
*
* @category Utilities
*
* @param input The JavaScript value to stringify.
* @param replacer Currently not supported.
* @param space A number for how many spaces each level of indentation gets, or a string used as indentation.
* Without this parameter, outputs flow-style (single-line) YAML.
* With this parameter, outputs block-style (multi-line) YAML.
* The number is clamped between 0 and 10, and the first 10 characters of the string are used.
* @returns A string containing the YAML document.
*
* @example
* ```ts
* import { YAML } from "bun";
*
* const input = {
* abc: "def",
* num: 123
* };
*
* // Without space - flow style (single-line)
* console.log(YAML.stringify(input));
* // {abc: def,num: 123}
*
* // With space - block style (multi-line)
* console.log(YAML.stringify(input, null, 2));
* // abc: def
* // num: 123
*
* const cycle = {};
* cycle.obj = cycle;
* console.log(YAML.stringify(cycle, null, 2));
* // &1
* // obj: *1
*/
export function stringify(input: unknown, replacer?: undefined | null, space?: string | number): string;
}
/**
* Markdown related APIs.
*
* Provides fast markdown parsing and rendering with three output modes:
* - `html()` โ render to an HTML string
* - `render()` โ render with custom callbacks for each element
* - `react()` โ parse to React-compatible JSX elements
*
* Supports GFM extensions (tables, strikethrough, task lists, autolinks) and
* component overrides to replace default HTML tags with custom components.
*
* @example
* ```tsx
* // Render markdown to HTML
* const html = Bun.markdown.html("# Hello **world**");
* // "<h1>Hello <strong>world</strong></h1>\n"
*
* // Render with custom callbacks
* const ansi = Bun.markdown.render("# Hello **world**", {
* heading: (children, { level }) => `\x1b[1m${children}\x1b[0m\n`,
* strong: (children) => `\x1b[1m${children}\x1b[22m`,
* paragraph: (children) => children + "\n",
* });
*
* // Render as a React component
* function Markdown({ text }: { text: string }) {
* return Bun.markdown.react(text);
* }
*
* // With component overrides
* const element = Bun.markdown.react("# Hello", { h1: MyHeadingComponent });
* ```
*/
namespace markdown {
/**
* Options for configuring the markdown parser.
*
* By default, GFM extensions (tables, strikethrough, task lists) are enabled.
*/
interface Options {
/** Enable GFM tables. Default: `true`. */
tables?: boolean;
/** Enable GFM strikethrough (`~~text~~`). Default: `true`. */
strikethrough?: boolean;
/** Enable GFM task lists (`- [x] item`). Default: `true`. */
tasklists?: boolean;
/** Treat soft line breaks as hard line breaks. Default: `false`. */
hardSoftBreaks?: boolean;
/** Enable wiki-style links (`[[target]]` or `[[target|label]]`). Default: `false`. */
wikiLinks?: boolean;
/** Enable underline syntax (`__text__` renders as `<u>` instead of `<strong>`). Default: `false`. */
underline?: boolean;
/** Enable LaTeX math (`$inline$` and `$$display$$`). Default: `false`. */
latexMath?: boolean;
/** Collapse whitespace in text content. Default: `false`. */
collapseWhitespace?: boolean;
/** Allow ATX headers without a space after `#`. Default: `false`. */
permissiveAtxHeaders?: boolean;
/** Disable indented code blocks. Default: `false`. */
noIndentedCodeBlocks?: boolean;
/** Disable HTML blocks. Default: `false`. */
noHtmlBlocks?: boolean;
/** Disable inline HTML spans. Default: `false`. */
noHtmlSpans?: boolean;
/**
* Enable the GFM tag filter, which replaces `<` with `<` for disallowed
* HTML tags (e.g. `<script>`, `<style>`, `<iframe>`). Default: `false`.
*/
tagFilter?: boolean;
/**
* Enable autolinks. Pass `true` to enable all autolink types (URL, WWW, email),
* or an object to enable individually.
*
* @example
* ```ts
* // Enable all autolinks
* { autolinks: true }
* // Enable only URL and email autolinks
* { autolinks: { url: true, email: true } }
* ```
*/
autolinks?: boolean | { url?: boolean; www?: boolean; email?: boolean };
/**
* Configure heading IDs and autolink headings. Pass `true` to enable both
* heading IDs and autolink headings, or an object to configure individually.
*
* @example
* ```ts
* // Enable both heading IDs and autolink headings
* { headings: true }
* // Enable only heading IDs
* { headings: { ids: true } }
* ```
*/
headings?: boolean | { ids?: boolean; autolink?: boolean };
}
/** A component that accepts props `P`: a function, class, or HTML tag name. */
type Component<P = {}> = string | ((props: P) => any) | (new (props: P) => any);
interface ChildrenProps {
children: import("./jsx.d.ts").JSX.Element[];
}
interface HeadingProps extends ChildrenProps {
/** Heading ID slug. Set when `headings: { ids: true }` is enabled. */
id?: string;
}
interface OrderedListProps extends ChildrenProps {
/** The start number. */
start: number;
}
interface ListItemProps extends ChildrenProps {
/** Task list checked state. Set for `- [x]` / `- [ ]` items. */
checked?: boolean;
}
interface CodeBlockProps extends ChildrenProps {
/** The info-string language (e.g. `"js"`). */
language?: string;
}
interface CellProps extends ChildrenProps {
/** Column alignment. */
align?: "left" | "center" | "right";
}
interface LinkProps extends ChildrenProps {
/** Link URL. */
href: string;
/** Link title attribute. */
title?: string;
}
interface ImageProps {
/** Image URL. */
src: string;
/** Alt text. */
alt?: string;
/** Image title attribute. */
title?: string;
}
/**
* Component overrides for `react()`.
*
* Replace default HTML tags with custom React components. Each override
* receives the same props the default element would get.
*
* @example
* ```tsx
* function Code({ language, children }: { language?: string; children: React.ReactNode }) {
* return <pre data-language={language}><code>{children}</code></pre>;
* }
* Bun.markdown.react(text, { pre: Code });
* ```
*/
interface ComponentOverrides {
h1?: Component<HeadingProps>;
h2?: Component<HeadingProps>;
h3?: Component<HeadingProps>;
h4?: Component<HeadingProps>;
h5?: Component<HeadingProps>;
h6?: Component<HeadingProps>;
p?: Component<ChildrenProps>;
blockquote?: Component<ChildrenProps>;
ul?: Component<ChildrenProps>;
ol?: Component<OrderedListProps>;
li?: Component<ListItemProps>;
pre?: Component<CodeBlockProps>;
hr?: Component<{}>;
html?: Component<ChildrenProps>;
table?: Component<ChildrenProps>;
thead?: Component<ChildrenProps>;
tbody?: Component<ChildrenProps>;
tr?: Component<ChildrenProps>;
th?: Component<CellProps>;
td?: Component<CellProps>;
em?: Component<ChildrenProps>;
strong?: Component<ChildrenProps>;
a?: Component<LinkProps>;
img?: Component<ImageProps>;
code?: Component<ChildrenProps>;
del?: Component<ChildrenProps>;
math?: Component<ChildrenProps>;
u?: Component<ChildrenProps>;
br?: Component<{}>;
}
/**
* Callbacks for `render()`. Each callback receives the accumulated children
* as a string and optional metadata, and returns a string.
*
* Return `null` or `undefined` to omit the element from the output.
* If no callback is registered for an element, its children pass through unchanged.
*/
/** Meta passed to the `heading` callback. */
interface HeadingMeta {
/** Heading level (1โ6). */
level: number;
/** Heading ID slug. Set when `headings: { ids: true }` is enabled. */
id?: string;
}
/** Meta passed to the `code` callback. */
interface CodeBlockMeta {
/** The info-string language (e.g. `"js"`). */
language?: string;
}
/** Meta passed to the `list` callback. */
interface ListMeta {
/** Whether this is an ordered list. */
ordered: boolean;
/** The start number for ordered lists. */
start?: number;
/** Nesting depth. `0` for a top-level list, `1` for a list inside a list item, etc. */
depth: number;
}
/** Meta passed to the `listItem` callback. */
interface ListItemMeta {
/** 0-based index of this item within its parent list. */
index: number;
/** Nesting depth of the parent list. `0` for items in a top-level list. */
depth: number;
/** Whether the parent list is ordered. */
ordered: boolean;
/** The start number of the parent list (only set when `ordered` is true). */
start?: number;
/** Task list checked state. Set for `- [x]` / `- [ ]` items. */
checked?: boolean;
}
/** Meta passed to `th` and `td` callbacks. */
interface CellMeta {
/** Column alignment. */
align?: "left" | "center" | "right";
}
/** Meta passed to the `link` callback. */
interface LinkMeta {
/** Link URL. */
href: string;
/** Link title attribute. */
title?: string;
}
/** Meta passed to the `image` callback. */
interface ImageMeta {
/** Image URL. */
src: string;
/** Image title attribute. */
title?: string;
}
interface RenderCallbacks {
/** Heading (level 1โ6). `id` is set when `headings: { ids: true }` is enabled. */
heading?: (children: string, meta: HeadingMeta) => string | null | undefined;
/** Paragraph. */
paragraph?: (children: string) => string | null | undefined;
/** Blockquote. */
blockquote?: (children: string) => string | null | undefined;
/** Code block. `meta.language` is the info-string (e.g. `"js"`). Only passed for fenced code blocks with a language. */
code?: (children: string, meta?: CodeBlockMeta) => string | null | undefined;
/** Ordered or unordered list. `start` is the first item number for ordered lists. */
list?: (children: string, meta: ListMeta) => string | null | undefined;
/** List item. `meta` always includes `{index, depth, ordered}`. `meta.start` is set for ordered lists; `meta.checked` is set for task list items. */
listItem?: (children: string, meta: ListItemMeta) => string | null | undefined;
/** Horizontal rule. */
hr?: (children: string) => string | null | undefined;
/** Table. */
table?: (children: string) => string | null | undefined;
/** Table head. */
thead?: (children: string) => string | null | undefined;
/** Table body. */
tbody?: (children: string) => string | null | undefined;
/** Table row. */
tr?: (children: string) => string | null | undefined;
/** Table header cell. `meta.align` is set when column alignment is specified. */
th?: (children: string, meta?: CellMeta) => string | null | undefined;
/** Table data cell. `meta.align` is set when column alignment is specified. */
td?: (children: string, meta?: CellMeta) => string | null | undefined;
/** Raw HTML content. */
html?: (children: string) => string | null | undefined;
/** Strong emphasis (`**text**`). */
strong?: (children: string) => string | null | undefined;
/** Emphasis (`*text*`). */
emphasis?: (children: string) => string | null | undefined;
/** Link. `href` is the URL, `title` is the optional title attribute. */
link?: (children: string, meta: LinkMeta) => string | null | undefined;
/** Image. `src` is the URL, `title` is the optional title attribute. */
image?: (children: string, meta: ImageMeta) => string | null | undefined;
/** Inline code (`` `code` ``). */
codespan?: (children: string) => string | null | undefined;
/** Strikethrough (`~~text~~`). */
strikethrough?: (children: string) => string | null | undefined;
/** Plain text content. */
text?: (text: string) => string | null | undefined;
}
/** Options for `react()` โ parser options and element symbol configuration. */
interface ReactOptions extends Options {
/**
* Which `$$typeof` symbol to use on the generated elements.
* - `19` (default): `Symbol.for('react.transitional.element')`
* - `18`: `Symbol.for('react.element')` โ use this for React 18 and older
*/
reactVersion?: 18 | 19;
}
/**
* Render markdown to an HTML string.
*
* @param input The markdown string or buffer to render
* @param options Parser options
* @returns An HTML string
*
* @example
* ```ts
* const html = Bun.markdown.html("# Hello **world**");
* // "<h1>Hello <strong>world</strong></h1>\n"
*
* // With options
* const html = Bun.markdown.html("## Hello", { headings: { ids: true } });
* // '<h2 id="hello">Hello</h2>\n'
* ```
*/
export function html(
input: string | NodeJS.TypedArray | DataView<ArrayBuffer> | ArrayBufferLike,
options?: Options,
): string;
/**
* Theme for ANSI terminal rendering.
*/
export interface AnsiTheme {
/**
* Emit ANSI color + styling escape sequences. When `false`, the
* renderer falls back to plain ASCII chrome (no box drawing,
* no emoji, no escape codes).
* @default true
*/
colors?: boolean;
/**
* Emit OSC 8 hyperlinks (clickable links in modern terminals).
* When `false`, links render as `text (url)`.
* @default false
*/
hyperlinks?: boolean;
/**
* True when the terminal background is light. Affects the color
* palette chosen for inline code backgrounds. Defaults to
* detecting from the `COLORFGBG` environment variable.
*/
light?: boolean;
/**
* Line width used for word-wrapping paragraphs and headings and
* for the horizontal rule. Pass `0` to disable wrapping.
* @default 80
*/
columns?: number;
/**
* Inline images using the Kitty Graphics Protocol when the `src`
* resolves to a local file on disk. Falls through to the text alt
* for remote URLs. Supported by Kitty, WezTerm, and Ghostty.
* @default false
*/
kittyGraphics?: boolean;
}
/**
* Render markdown to an ANSI-colored terminal string.
*
* Supports headings, lists, tables, inline styles, syntax-highlighted
* code blocks, links, images, and blockquotes. By default, enables all
* GFM extensions plus wikilinks, underline, and LaTeX math.
*
* @param input The markdown string or buffer to render
* @param theme Optional theme overrides
* @returns An ANSI-colored string
*
* @example
* ```ts
* const out = Bun.markdown.ansi("# Hello\n\n**bold** and *italic*\n");
* process.stdout.write(out);
*
* // Plain text, no escape codes
* const plain = Bun.markdown.ansi("# Hello", { colors: false });
*
* // Enable clickable OSC 8 hyperlinks
* const linked = Bun.markdown.ansi("[docs](https://bun.com)", {
* hyperlinks: true,
* });
*
* // Inline images via Kitty Graphics Protocol
* const withImg = Bun.markdown.ansi("", {
* kittyGraphics: true,
* });
*
* // Custom width
* const wrapped = Bun.markdown.ansi(longText, { columns: 60 });
* ```
*/
export function ansi(
input: string | NodeJS.TypedArray | DataView<ArrayBuffer> | ArrayBufferLike,
theme?: AnsiTheme,
): string;
/**
* Render markdown with custom JavaScript callbacks for each element.
*
* Each callback receives the accumulated children as a string and optional
* metadata, and returns a string. Return `null` or `undefined` to omit
* an element. If no callback is registered, children pass through unchanged.
*
* Parser options are passed as a separate third argument.
*
* @param input The markdown string to render
* @param callbacks Callbacks for each element type
* @param options Parser options
* @returns The accumulated string output
*
* @example
* ```ts
* // Custom HTML with classes
* const html = Bun.markdown.render("# Title\n\nHello **world**", {
* heading: (children, { level }) => `<h${level} class="title">${children}</h${level}>`,
* paragraph: (children) => `<p>${children}</p>`,
* strong: (children) => `<b>${children}</b>`,
* });
*
* // ANSI terminal output
* const ansi = Bun.markdown.render("# Hello\n\n**bold**", {
* he