# Runtime



Clusterbase functions run in V8 isolates — lightweight sandboxes using the same JavaScript engine as Chrome. Each function gets its own isolate with a full set of Web APIs.

## Available APIs [#available-apis]

### HTTP [#http]

| API               | Description                                                                                           |
| ----------------- | ----------------------------------------------------------------------------------------------------- |
| `Request`         | Standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object                   |
| `Response`        | Standard [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) with `Response.json()` |
| `Headers`         | Standard [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers)                          |
| `fetch()`         | Make HTTP requests from your handler                                                                  |
| `URL`             | URL parsing and construction                                                                          |
| `URLSearchParams` | Query string manipulation                                                                             |
| `URLPattern`      | Pattern matching for URLs                                                                             |
| `FormData`        | Multipart form data                                                                                   |

### Encoding [#encoding]

| API           | Description                          |
| ------------- | ------------------------------------ |
| `TextEncoder` | Encode strings to UTF-8 `Uint8Array` |
| `TextDecoder` | Decode `Uint8Array` to strings       |
| `atob()`      | Decode base64 to string              |
| `btoa()`      | Encode string to base64              |

### Crypto [#crypto]

| API                                         | Description                              |
| ------------------------------------------- | ---------------------------------------- |
| `crypto.subtle.digest()`                    | SHA-1, SHA-256, SHA-384, SHA-512         |
| `crypto.subtle.sign()` / `verify()`         | HMAC, RSA-PSS, RSASSA-PKCS1-v1\_5, ECDSA |
| `crypto.subtle.encrypt()` / `decrypt()`     | AES-CBC, AES-CTR, AES-GCM, RSA-OAEP      |
| `crypto.subtle.generateKey()`               | Generate key pairs and symmetric keys    |
| `crypto.subtle.importKey()` / `exportKey()` | Import/export keys in various formats    |
| `crypto.getRandomValues()`                  | Cryptographically secure random bytes    |
| `crypto.randomUUID()`                       | Generate a random UUID v4                |

Algorithm names passed to `crypto.subtle` methods (e.g. `"hmac"`, `"Sha-256"`) are matched case-insensitively, per spec. Unsupported algorithm names throw a `DOMException` with name `NotSupportedError`.

### Streams [#streams]

| API                   | Description                    |
| --------------------- | ------------------------------ |
| `ReadableStream`      | Read data incrementally        |
| `WritableStream`      | Write data incrementally       |
| `TransformStream`     | Transform data between streams |
| `CompressionStream`   | gzip/deflate compression       |
| `DecompressionStream` | gzip/deflate decompression     |

### Globals [#globals]

| API                                    | Description                                                                                                                      |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `console.log()` / `error()` / `warn()` | Logging (captured by Clusterbase)                                                                                                |
| `setTimeout()` / `setInterval()`       | Timers                                                                                                                           |
| `clearTimeout()` / `clearInterval()`   | Cancel timers                                                                                                                    |
| `AbortController` / `AbortSignal`      | Cancel async operations                                                                                                          |
| `Blob`                                 | Binary data container                                                                                                            |
| `File`                                 | File-like object (extends Blob)                                                                                                  |
| `Event` / `EventTarget`                | Event system                                                                                                                     |
| `DOMException`                         | Standard [DOMException](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) thrown by Web APIs (e.g. `crypto.subtle`) |
| `navigator.userAgent`                  | Returns `"Cluster"`                                                                                                              |
| `process.env`                          | Environment variables                                                                                                            |
| `queueMicrotask()`                     | Queue a microtask                                                                                                                |
| `structuredClone()`                    | Deep clone objects                                                                                                               |
| `performance.now()`                    | Monotonic milliseconds since isolate start (never decreases, even if the wall clock moves backward)                              |
| `performance.timeOrigin` / `toJSON()`  | Wall-clock origin the isolate started from                                                                                       |

## V8 Version [#v8-version]

The runtime uses V8 **146.9.0** with:

* Full ES2024 support
* ICU 77 for internationalization (`Intl.*` APIs)
* WebAssembly support

## Limitations [#limitations]

* **No Node.js APIs** — no `fs`, `path`, `os`, `child_process`, `net`, `http`, `Buffer`
* **No `require()`** — use ES module `import`/`export` (the bundler handles modules for you)
* **No `eval()` by default** — enable with `--allow-code-generation` in dev, not available in production
* **30-second timeout** — requests that exceed 30 seconds are terminated
* **No persistent state** — isolates may be recycled between requests. Use external services for state
* **`fetch()` reaches public hosts only** — requests to internal or private destinations are blocked at connect time and reject with `fetch blocked: destination is an internal/private address`. This covers loopback, private ranges (RFC1918, CGNAT), link-local including the cloud metadata endpoint (`169.254.169.254`), and other reserved/internal addresses, for both IP literals and hostnames that resolve (or redirect) to them.

## Example: Crypto [#example-crypto]

```ts
export async function handler(request: Request): Promise<Response> {
  const body = await request.text();
  const encoded = new TextEncoder().encode(body);
  const hash = await crypto.subtle.digest("SHA-256", encoded);
  const hex = [...new Uint8Array(hash)]
    .map(b => b.toString(16).padStart(2, "0"))
    .join("");
  return Response.json({ sha256: hex });
}
```

## Example: Streaming [#example-streaming]

```ts
export function handler(request: Request): Response {
  const stream = new ReadableStream({
    start(controller) {
      controller.enqueue(new TextEncoder().encode("Hello "));
      controller.enqueue(new TextEncoder().encode("World!"));
      controller.close();
    },
  });
  return new Response(stream);
}
```
