> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/oven-sh/bun/llms.txt
> Use this file to discover all available pages before exploring further.

# Web APIs

> Bun implements Web-standard APIs so your server-side code shares the same interfaces as the browser.

Bun implements Web-standard APIs wherever possible instead of inventing new ones. This means code written for the browser (or other modern runtimes like Deno and Cloudflare Workers) often runs in Bun without changes.

Browser-only APIs like the DOM or History API have no meaning in a server context and are not included. Everything else that makes sense server-side is implemented.

## HTTP

`fetch`, `Request`, `Response`, and `Headers` are all globally available. No import is needed.

```typescript theme={null}
// fetch is available globally
const response = await fetch("https://example.com/api/data");
const data = await response.json();

// Construct requests and responses manually
const req = new Request("https://example.com", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ hello: "world" }),
});

const res = new Response(JSON.stringify({ ok: true }), {
  status: 200,
  headers: { "Content-Type": "application/json" },
});
```

### AbortController

Use `AbortController` to cancel in-flight fetch requests.

```typescript theme={null}
const controller = new AbortController();
const { signal } = controller;

setTimeout(() => controller.abort(), 5000);

const response = await fetch("https://example.com", { signal });
```

## URLs

`URL` and `URLSearchParams` are globally available and work identically to their browser counterparts.

```typescript theme={null}
const url = new URL("https://example.com/path?foo=bar&baz=qux");
console.log(url.hostname);       // "example.com"
console.log(url.pathname);       // "/path"
console.log(url.searchParams.get("foo")); // "bar"

const params = new URLSearchParams({ page: "2", limit: "50" });
console.log(params.toString()); // "page=2&limit=50"
```

## Streams

Bun fully implements the WHATWG Streams API.

<CardGroup cols={2}>
  <Card title="ReadableStream" icon="arrow-right">
    A stream of data you can read from, chunk by chunk.
  </Card>

  <Card title="WritableStream" icon="arrow-left">
    A stream of data you can write to.
  </Card>

  <Card title="TransformStream" icon="arrows-left-right">
    A writable stream that produces a readable stream after transformation.
  </Card>

  <Card title="Queuing strategies" icon="list">
    `ByteLengthQueuingStrategy` and `CountQueuingStrategy` for backpressure control.
  </Card>
</CardGroup>

```typescript theme={null}
// Create a ReadableStream from scratch
const stream = new ReadableStream({
  start(controller) {
    controller.enqueue("hello ");
    controller.enqueue("world");
    controller.close();
  },
});

// Pipe through a TransformStream
const upperCaseStream = new TransformStream({
  transform(chunk, controller) {
    controller.enqueue(chunk.toUpperCase());
  },
});

const reader = stream.pipeThrough(upperCaseStream).getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(value); // "HELLO ", then "WORLD"
}
```

## Blob and File

`Blob` represents raw binary data. `File` extends `Blob` with a `name` and `lastModified`.

```typescript theme={null}
const blob = new Blob(["hello world"], { type: "text/plain" });
console.log(blob.size);         // 11
console.log(blob.type);         // "text/plain"
const text = await blob.text(); // "hello world"

const file = new File(["file contents"], "hello.txt", { type: "text/plain" });
console.log(file.name);         // "hello.txt"
```

## FormData

`FormData` is fully implemented, including file uploads.

```typescript theme={null}
const form = new FormData();
form.append("username", "alice");
form.append("avatar", new File(["..."], "avatar.png", { type: "image/png" }));

const response = await fetch("https://example.com/upload", {
  method: "POST",
  body: form,
});
```

## WebSocket

`WebSocket` is available globally for connecting to WebSocket servers.

```typescript theme={null}
const ws = new WebSocket("wss://echo.websocket.org");

ws.addEventListener("open", () => {
  ws.send("hello server");
});

ws.addEventListener("message", (event) => {
  console.log("received:", event.data);
  ws.close();
});
```

<Tip>
  Bun also has a high-performance server-side WebSocket API via `Bun.serve`. See the [WebSockets](/runtime/websockets) page.
</Tip>

## Web Crypto

The Web Crypto API (`crypto`, `SubtleCrypto`, `CryptoKey`) is available globally.

```typescript theme={null}
// Generate a random UUID
const id = crypto.randomUUID();

// Fill a buffer with random bytes
const buffer = new Uint8Array(32);
crypto.getRandomValues(buffer);

// Use SubtleCrypto for hashing
const encoder = new TextEncoder();
const data = encoder.encode("hello world");
const hash = await crypto.subtle.digest("SHA-256", data);
const hex = Buffer.from(hash).toString("hex");
console.log(hex);
```

<CodeGroup>
  ```typescript generate-key.ts theme={null}
  // Generate an AES-GCM key
  const key = await crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"],
  );
  ```

  ```typescript hmac.ts theme={null}
  // Sign data with HMAC
  const key = await crypto.subtle.importKey(
    "raw",
    new TextEncoder().encode("secret"),
    { name: "HMAC", hash: "SHA-256" },
    false,
    ["sign", "verify"],
  );
  const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode("message"));
  ```
</CodeGroup>

## Encoding

`TextEncoder` and `TextDecoder` convert between strings and binary data. `atob` and `btoa` handle base64.

```typescript theme={null}
const encoder = new TextEncoder();
const bytes = encoder.encode("hello"); // Uint8Array

const decoder = new TextDecoder();
const str = decoder.decode(bytes); // "hello"

// Base64
const b64 = btoa("hello world");   // "aGVsbG8gd29ybGQ="
const raw = atob(b64);             // "hello world"
```

## Timers

All standard timer functions are globally available.

```typescript theme={null}
// Run after a delay
const id = setTimeout(() => console.log("fired"), 1000);
clearTimeout(id);

// Run repeatedly
const interval = setInterval(() => console.log("tick"), 500);
clearInterval(interval);

// Run after current task, before next I/O event
setImmediate(() => console.log("immediate"));

// Enqueue a microtask
queueMicrotask(() => console.log("microtask"));
```

## Console

`console` matches the browser and Node.js APIs.

```typescript theme={null}
console.log("plain log");
console.info("info message");
console.warn("warning");
console.error("error message");
console.table([{ name: "alice", age: 30 }, { name: "bob", age: 25 }]);
console.time("label");
// ... work ...
console.timeEnd("label");
```

## Performance

`performance` is available globally for measuring timing.

```typescript theme={null}
const start = performance.now();
// ... do work ...
const end = performance.now();
console.log(`elapsed: ${end - start}ms`);

performance.mark("start");
// ... do work ...
performance.mark("end");
performance.measure("my task", "start", "end");
```

## Events

The full event system is implemented.

```typescript theme={null}
const target = new EventTarget();

target.addEventListener("greet", (event) => {
  console.log((event as CustomEvent).detail); // "hello"
});

target.dispatchEvent(new CustomEvent("greet", { detail: "hello" }));
```

## Workers

`Worker` (Web Workers API) is available for running JavaScript on background threads.

```typescript theme={null}
const worker = new Worker(new URL("./worker.ts", import.meta.url));

worker.postMessage({ type: "ping" });

worker.onmessage = (event) => {
  console.log(event.data); // response from worker
};
```

<Tip>
  For a full guide on workers and inter-thread communication, see the [Workers](/runtime/workers) page.
</Tip>

## Hashing and passwords

### `Bun.hash()`

`Bun.hash()` provides fast non-cryptographic hashing using Wyhash (default) and several other algorithms:

```typescript theme={null}
Bun.hash("hello world");         // number (Wyhash)
Bun.hash.wyhash("hello world");  // number
Bun.hash.crc32("hello world");   // number
Bun.hash.adler32("hello world"); // number
Bun.hash.cityHash32("data");     // number
Bun.hash.cityHash64("data");     // bigint
Bun.hash.murmur32v3("data");     // number
Bun.hash.murmur64v2("data");     // bigint
```

All variants accept `string`, `ArrayBuffer`, `TypedArray`, or `DataView`. An optional seed can be passed as the second argument.

### `Bun.password`

`Bun.password` provides secure password hashing using Argon2 (default) or bcrypt:

```typescript theme={null}
const password = "super-secure-pa$$word";

// Hash using argon2id (default, recommended)
const hash = await Bun.password.hash(password);
// => "$argon2id$v=19$m=65536,t=2,p=1$..."

// Verify a password against its hash
const isMatch = await Bun.password.verify(password, hash);
// => true
```

Configure the algorithm and its parameters:

```typescript theme={null}
// Argon2 with custom parameters
const argonHash = await Bun.password.hash(password, {
  algorithm: "argon2id", // "argon2id" | "argon2i" | "argon2d"
  memoryCost: 4,         // memory in kibibytes
  timeCost: 3,           // number of iterations
});

// bcrypt
const bcryptHash = await Bun.password.hash(password, {
  algorithm: "bcrypt",
  cost: 10, // 4–31
});
```

`verify()` auto-detects the algorithm from the hash format (PHC for Argon2, MCF for bcrypt).

## Supported APIs reference

| Category         | APIs                                                                                                       |
| ---------------- | ---------------------------------------------------------------------------------------------------------- |
| HTTP             | `fetch`, `Request`, `Response`, `Headers`, `AbortController`, `AbortSignal`                                |
| URLs             | `URL`, `URLSearchParams`                                                                                   |
| Streams          | `ReadableStream`, `WritableStream`, `TransformStream`, `ByteLengthQueuingStrategy`, `CountQueuingStrategy` |
| Blob             | `Blob`, `File`, `FormData`                                                                                 |
| WebSockets       | `WebSocket`                                                                                                |
| Crypto           | `crypto`, `SubtleCrypto`, `CryptoKey`, `Crypto`                                                            |
| Encoding         | `TextEncoder`, `TextDecoder`, `TextEncoderStream`, `TextDecoderStream`, `atob`, `btoa`                     |
| Timers           | `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval`, `setImmediate`, `clearImmediate`             |
| Microtasks       | `queueMicrotask`                                                                                           |
| Events           | `EventTarget`, `Event`, `CustomEvent`, `ErrorEvent`, `CloseEvent`, `MessageEvent`                          |
| Workers          | `Worker`, `MessageChannel`, `MessagePort`, `BroadcastChannel`                                              |
| Debugging        | `console`, `performance`                                                                                   |
| User interaction | `alert`, `confirm`, `prompt` (intended for interactive CLIs)                                               |
| Compression      | `CompressionStream`, `DecompressionStream`                                                                 |
| Realms           | `ShadowRealm`                                                                                              |
| JSON             | `JSON`                                                                                                     |
| Other            | `structuredClone`, `reportError`, `WebAssembly`                                                            |
