# Code samples

> Runnable Elide samples in TypeScript, JavaScript, Java, Kotlin, Python and WebAssembly: HTTP servers, SQLite, files, streams, workers, coroutines, JSON, Maven dependencies, annotations, tests, interop and OpenTelemetry, each with its command and output.

Run each sample in an empty directory.

## TypeScript without a build

Generics, union types and `satisfies` run directly, with no build step or `tsconfig.json`.

```ts
// shapes.ts
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "rect"; width: number; height: number };

function area(shape: Shape): number {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "rect":
      return shape.width * shape.height;
  }
}

function largest<T>(items: T[], size: (item: T) => number): T {
  return items.reduce((a, b) => (size(b) > size(a) ? b : a));
}

const shapes = [
  { kind: "circle", radius: 2 },
  { kind: "rect", width: 3, height: 5 },
] satisfies Shape[];

for (const s of shapes) console.log(`${s.kind}: ${area(s).toFixed(2)}`);
console.log(`largest: ${largest(shapes, area).kind}`);
```

```bash
elide run shapes.ts
```

```text
circle: 12.57
rect: 15.00
largest: rect
```

## HTTP handler

```ts
// server.ts
export default {
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);
    return Response.json({ path: url.pathname });
  },
};
```

```bash
elide serve --no-tui server.ts
curl http://127.0.0.1:8080/hello
```

```text
{"path":"/hello"}
```

## Routes with URLPattern

Matches request paths with `URLPattern` in a handler served by `elide serve`.

```ts
// api.ts
const users = new Map([
  ["1", { id: 1, name: "Ada" }],
  ["2", { id: 2, name: "Grace" }],
]);

const userRoute = new URLPattern({ pathname: "/users/:id" });

export default {
  async fetch(request: Request): Promise<Response> {
    const match = userRoute.exec(request.url);
    if (!match) return new Response("Not found\n", { status: 404 });
    const user = users.get(match.pathname.groups.id!);
    return user ? Response.json(user) : Response.json({ error: "no such user" }, { status: 404 });
  },
};
```

```bash
elide serve --no-tui api.ts
curl -s http://127.0.0.1:8080/users/2; echo
curl -s -w ' %{http_code}\n' http://127.0.0.1:8080/users/9
```

```text
{"id":2,"name":"Grace"}
{"error":"no such user"} 404
```

## Local server and fetch

Starts a `node:http` server on a free port, calls it with `fetch`, and shuts it down.

```ts
// roundtrip.ts
import { createServer } from "node:http";
import type { AddressInfo } from "node:net";

const server = createServer((req, res) => {
  let body = "";
  req.on("data", (chunk) => (body += chunk));
  req.on("end", () => {
    const { items } = JSON.parse(body) as { items: number[] };
    res.setHeader("content-type", "application/json");
    res.end(JSON.stringify({ count: items.length, sum: items.reduce((a, b) => a + b, 0) }));
  });
});

server.listen(0, "127.0.0.1", async () => {
  const { port } = server.address() as AddressInfo;
  const response = await fetch(`http://127.0.0.1:${port}/sum`, {
    method: "POST",
    body: JSON.stringify({ items: [4, 8, 15, 16, 23, 42] }),
  });
  console.log(response.status, response.headers.get("content-type"));
  console.log(JSON.stringify(await response.json()));
  server.close();
});
```

```bash
elide run roundtrip.ts
```

```text
200 application/json
{"count":6,"sum":108}
```

## Embedded SQLite

```ts
// database.ts
import { Database } from "elide:sqlite";

const db = new Database();
db.exec("CREATE TABLE users (name TEXT)");
db.exec("INSERT INTO users VALUES ('Ada')");
console.log(db.query("SELECT name FROM users").get().name);
```

```bash
elide run database.ts
```

```text
Ada
```

## SQLite transactions

Moves money between accounts in a SQLite transaction that rolls back when a balance would go negative.

```ts
// bank.ts
import { Database } from "elide:sqlite";

const db = new Database();
db.exec("CREATE TABLE accounts (name TEXT PRIMARY KEY, balance INTEGER NOT NULL)");
const open = db.prepare("INSERT INTO accounts VALUES ($name, $balance)");
open.run({ $name: "alice", $balance: 100 });
open.run({ $name: "bob", $balance: 20 });

const adjust = db.prepare("UPDATE accounts SET balance = balance + ? WHERE name = ?");
const balance = db.prepare("SELECT balance FROM accounts WHERE name = ?");

const transfer = db.transaction((from: string, to: string, amount: number) => {
  adjust.run(-amount, from);
  adjust.run(amount, to);
  if (balance.get(from).balance < 0) throw new Error(`${from} cannot send ${amount}`);
});

transfer("alice", "bob", 30);
try {
  transfer("bob", "alice", 500);
} catch (e) {
  console.log("rolled back:", (e as Error).message);
}

for (const [name, amount] of db.prepare("SELECT name, balance FROM accounts ORDER BY name").values()) {
  console.log(name, amount);
}
```

```bash
elide run bank.ts
```

```text
rolled back: bob cannot send 500
alice 70
bob 50
```

## Access rules with CEL

Compiles permission rules written in CEL once with `elide:cel`, then checks them against each user and document. CEL expressions have no side effects and always terminate, so rules can come from configuration.

```ts
// rules.ts
import { compile } from "elide:cel";

const rules = {
  "read": "true",
  "edit": "user.id == doc.owner || 'admin' in user.roles",
  "export": "user.plan == 'pro' && !doc.tags.exists(t, t.startsWith('pii'))",
};
const programs = Object.entries(rules).map(([name, rule]) => ({ name, program: compile(rule) }));

const docs = [
  { id: 1, owner: "ada", tags: ["report"] },
  { id: 2, owner: "grace", tags: ["pii-email", "report"] },
];
const users = [
  { id: "ada", plan: "pro", roles: [] },
  { id: "grace", plan: "free", roles: ["admin"] },
];

for (const user of users) {
  for (const doc of docs) {
    const allowed = programs.filter(({ program }) => program.test({ user, doc }));
    console.log(`${user.id} on doc ${doc.id}: ${allowed.map(({ name }) => name).join(", ")}`);
  }
}

console.log("export reads:", programs[2]?.program.variables.join(", "));
```

```bash
elide run rules.ts
```

```text
ada on doc 1: read, edit, export
ada on doc 2: read
grace on doc 1: read, edit
grace on doc 2: read, edit
export reads: doc, user
```

## Files and paths

Writes a small directory tree with `node:fs`, then walks it and totals file sizes by extension.

```ts
// sizes.ts
import { mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
import { extname, join } from "node:path";

mkdirSync("site/css", { recursive: true });
writeFileSync("site/index.html", "<h1>Home</h1>");
writeFileSync("site/about.html", "<h1>About us</h1>");
writeFileSync("site/css/main.css", "body { margin: 0 }");

const totals = new Map<string, number>();
for (const entry of readdirSync("site", { recursive: true, withFileTypes: true })) {
  if (!entry.isFile()) continue;
  const ext = extname(entry.name);
  const size = statSync(join(entry.parentPath, entry.name)).size;
  totals.set(ext, (totals.get(ext) ?? 0) + size);
}

for (const [ext, bytes] of [...totals].sort()) console.log(`${ext}: ${bytes} bytes`);
```

```bash
elide run sizes.ts
```

```text
.css: 18 bytes
.html: 30 bytes
```

## CSV report

Parses a CSV file and prints revenue per region, largest first.

```text
# sales.csv
region,product,units,price
north,widget,12,2.50
south,widget,4,2.50
north,gadget,3,10.00
east,gizmo,7,4.00
south,gadget,6,10.00
```

```ts
// report.ts
import { readFileSync } from "node:fs";

type Row = { region: string; product: string; units: number; price: number };

const [header, ...lines] = readFileSync("sales.csv", "utf8").trim().split("\n");
const keys = header.split(",");
const rows: Row[] = lines.map((line) => {
  const v = line.split(",");
  return { region: v[0], product: v[1], units: Number(v[2]), price: Number(v[3]) };
});

const revenue = new Map<string, number>();
for (const r of rows) revenue.set(r.region, (revenue.get(r.region) ?? 0) + r.units * r.price);

console.log(`${keys.length} columns, ${rows.length} rows`);
for (const [region, total] of [...revenue].sort((a, b) => b[1] - a[1])) {
  console.log(`${region.padEnd(6)} ${total.toFixed(2).padStart(8)}`);
}
```

```bash
elide run report.ts
```

```text
4 columns, 5 rows
south     70.00
north     60.00
east      28.00
```

## Streams and async iteration

Reads a log file line by line with `node:readline` and counts entries per level.

```javascript
// levels.mjs
import { createReadStream, writeFileSync } from "node:fs";
import { createInterface } from "node:readline";

writeFileSync("app.log", [
  "INFO server started",
  "WARN slow query: 812ms",
  "INFO request /users",
  "ERROR connection reset",
  "INFO request /orders",
].join("\n"));

const counts = {};
const lines = createInterface({ input: createReadStream("app.log") });
for await (const line of lines) {
  const level = line.split(" ", 1)[0];
  counts[level] = (counts[level] ?? 0) + 1;
}
console.log(JSON.stringify(counts));
```

```bash
elide run levels.mjs
```

```text
{"INFO":3,"WARN":1,"ERROR":1}
```

## Transform stream pipeline

Chains a generator source, a `Transform` and a writable sink with `pipeline` from `node:stream/promises`.

```javascript
// pipeline.mjs
import { Readable, Transform, Writable } from "node:stream";
import { pipeline } from "node:stream/promises";

async function* records() {
  yield { sku: "A-1", qty: 3, price: 4.5 };
  yield { sku: "B-7", qty: 1, price: 19.99 };
  yield { sku: "C-2", qty: 10, price: 0.25 };
}

const toCsv = new Transform({
  objectMode: true,
  transform(r, _enc, done) {
    done(null, `${r.sku},${r.qty},${(r.qty * r.price).toFixed(2)}\n`);
  },
});

const lines = [];
const sink = new Writable({
  objectMode: true,
  write(chunk, _enc, done) {
    lines.push(chunk.toString().trim());
    done();
  },
});

await pipeline(Readable.from(records()), toCsv, sink);
console.log(["sku,qty,total", ...lines].join("\n"));
```

```bash
elide run pipeline.mjs
```

```text
sku,qty,total
A-1,3,13.50
B-7,1,19.99
C-2,10,2.50
```

## Command-line arguments

Parses flags and positional arguments with `parseArgs` from `node:util`.

```javascript
// greet.mjs
import { parseArgs } from "node:util";

const { values, positionals } = parseArgs({
  args: process.argv.slice(2),
  options: {
    greeting: { type: "string", short: "g", default: "Hello" },
    shout: { type: "boolean", default: false },
  },
  allowPositionals: true,
});

for (const name of positionals) {
  const line = `${values.greeting}, ${name}!`;
  console.log(values.shout ? line.toUpperCase() : line);
}
```

```bash
elide run greet.mjs -- --greeting Hi Ada Grace
elide run greet.mjs -- --shout Alan
```

```text
Hi, Ada!
Hi, Grace!
HELLO, ALAN!
```

## Worker threads

Counts primes below 200,000 in four `node:worker_threads` workers and adds up their results.

```javascript
// primes.mjs
import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";

function countPrimes(from, to) {
  let count = 0;
  for (let n = Math.max(from, 2); n < to; n++) {
    let prime = true;
    for (let d = 2; d * d <= n; d++) if (n % d === 0) { prime = false; break; }
    if (prime) count++;
  }
  return count;
}

if (isMainThread) {
  const limit = 200_000, parts = 4, step = limit / parts;
  const jobs = Array.from({ length: parts }, (_, i) =>
    new Promise((resolve, reject) => {
      const w = new Worker(new URL(import.meta.url), { workerData: [i * step, (i + 1) * step] });
      w.once("message", resolve);
      w.once("error", reject);
    }));
  const counts = await Promise.all(jobs);
  console.log("per worker:", counts.join(", "));
  console.log("primes below", limit, "=", counts.reduce((a, b) => a + b));
} else {
  parentPort.postMessage(countPrimes(...workerData));
}
```

```bash
elide run primes.mjs
```

```text
per worker: 5133, 4459, 4256, 4136
primes below 200000 = 17984
```

## TypeScript tests

Runs `node:test` tests written in TypeScript with `elide test`, with no configuration. `--reporter=tap` prints TAP instead of the summary.

```ts
// slugify.ts
export function slugify(title: string): string {
  return title
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-|-$/g, "");
}
```

```ts
// slugify.test.ts
import { describe, test } from "node:test";
import assert from "node:assert";
import { slugify } from "./slugify.ts";

describe("slugify", () => {
  test("lowercases and joins words", () => {
    assert.equal(slugify("Hello World"), "hello-world");
  });

  test("drops punctuation at the ends", () => {
    assert.equal(slugify("  Elide: a runtime! "), "elide-a-runtime");
  });
});
```

```bash
elide test --reporter=tap
```

```text
TAP version 13
# start 1: slugify > lowercases and joins words
ok 1 - slugify > lowercases and joins words
# start 2: slugify > drops punctuation at the ends
ok 2 - slugify > drops punctuation at the ends
1..2
```

## Java records and streams

Runs a single Java file with records, switch expressions and streams, with no build file.

```java
// Payroll.java
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class Payroll {
  enum Role { ENGINEER, DESIGNER, MANAGER }

  record Employee(String name, Role role, int salary) {}

  public static void main(String[] args) {
    var staff = List.of(
        new Employee("Ada", Role.ENGINEER, 120_000),
        new Employee("Linus", Role.ENGINEER, 110_000),
        new Employee("Susan", Role.DESIGNER, 95_000),
        new Employee("Grace", Role.MANAGER, 130_000));

    Map<Role, Double> average = staff.stream().collect(
        Collectors.groupingBy(Employee::role, TreeMap::new, Collectors.averagingInt(Employee::salary)));

    average.forEach((role, avg) -> {
      String label = switch (role) {
        case ENGINEER -> "Engineering";
        case DESIGNER -> "Design";
        case MANAGER -> "Management";
      };
      System.out.printf("%-12s %,8.0f%n", label, avg);
    });
  }
}
```

```bash
elide run Payroll.java
```

```text
Engineering   115,000
Design         95,000
Management    130,000
```

## Kotlin collections

Groups, sums, sorts and partitions a list of orders with the Kotlin standard library.

```kotlin
// Orders.kt
data class Order(val customer: String, val item: String, val amount: Double)

fun main() {
  val orders = listOf(
    Order("ada", "book", 24.0),
    Order("grace", "laptop", 1299.0),
    Order("ada", "pen", 3.5),
    Order("alan", "book", 24.0),
    Order("grace", "mouse", 25.0),
  )

  orders.groupBy { it.customer }
    .mapValues { (_, list) -> list.sumOf { it.amount } }
    .entries
    .sortedByDescending { it.value }
    .forEach { (customer, total) -> println("%-6s %8.2f".format(customer, total)) }

  val (books, other) = orders.partition { it.item == "book" }
  println("books: ${books.size}, other items: ${other.map { it.item }.distinct().sorted()}")
}
```

```bash
elide run Orders.kt
```

```text
grace   1324.00
ada       27.50
alan      24.00
books: 2, other items: [laptop, mouse, pen]
```

## Kotlin tests

Runs `kotlin.test` tests with `elide test` in a project with an `elide.pkl`. `--reporter=tap` prints TAP instead of the summary.

```pkl
// elide.pkl
amends "elide:project.pkl"

name = "pricing"
```

```kotlin
// src/main/kotlin/Pricing.kt
fun priceWithTax(net: Double, ratePercent: Int): Double = Math.round(net * (100 + ratePercent)) / 100.0
```

```kotlin
// src/test/kotlin/PricingTest.kt
import kotlin.test.Test
import kotlin.test.assertEquals

class PricingTest {
  @Test
  fun addsTax() {
    assertEquals(12.0, priceWithTax(10.0, 20))
  }

  @Test
  fun roundsToCents() {
    assertEquals(10.69, priceWithTax(9.99, 7))
  }
}
```

```bash
elide test --reporter=tap
```

```text
TAP version 13
# start 1: PricingTest > addsTax()
ok 1 - PricingTest > addsTax()
# start 2: PricingTest > roundsToCents()
ok 2 - PricingTest > roundsToCents()
1..2
```

## Kotlin coroutines

Starts three loads with `async` and waits for all of them; the shortest delay finishes first. kotlinx.coroutines is
bundled, so a single file needs no build file.

```kotlin
// Fetch.kt
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

suspend fun load(name: String, ms: Long): Int {
  delay(ms)
  println("loaded $name")
  return name.length
}

fun main() = runBlocking {
  val sizes = listOf("users" to 300L, "orders" to 200L, "prices" to 100L)
    .map { (name, ms) -> async { load(name, ms) } }
    .awaitAll()
  println("sizes in request order: $sizes")
}
```

```bash
elide run Fetch.kt
```

```text
loaded prices
loaded orders
loaded users
sizes in request order: [5, 6, 6]
```

## Kotlin JSON serialization

Decodes JSON into a `@Serializable` data class, filling defaults, and encodes a copy. The serialization plugin and
runtime are bundled.

```kotlin
// Config.kt
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json

@Serializable
data class Server(val host: String, val port: Int = 8080, val tags: List<String> = emptyList())

fun main() {
  val json = Json { prettyPrint = true }
  val server = json.decodeFromString<Server>("""{"host": "localhost", "tags": ["dev"]}""")
  println(server)
  println(json.encodeToString(server.copy(port = 9090)))
}
```

```bash
elide run Config.kt
```

```text
Server(host=localhost, port=8080, tags=[dev])
{
    "host": "localhost",
    "port": 9090,
    "tags": [
        "dev"
    ]
}
```

## Java with a Maven dependency

Declares Gson in `elide.pkl`; `elide run` resolves it, compiles and runs `jvm.main`.

```pkl
// elide.pkl
amends "elide:project.pkl"

name = "inventory"

jvm {
  main = "app.Inventory"
}

dependencies {
  maven {
    packages { "com.google.code.gson:gson:2.13.1" }
  }
}
```

```java
// src/main/java/app/Inventory.java
package app;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.List;

public class Inventory {
  record Item(String sku, int quantity, double price) {}

  public static void main(String[] args) {
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    Item[] items = gson.fromJson("""
        [{"sku": "A-1", "quantity": 3, "price": 2.5},
         {"sku": "B-2", "quantity": 1, "price": 10.0}]
        """, Item[].class);

    double total = List.of(items).stream().mapToDouble(i -> i.quantity() * i.price()).sum();
    System.out.println(items.length + " items, total " + total);
    System.out.println(gson.toJson(items[0]));
  }
}
```

```bash
elide run
```

```text
2 items, total 17.5
{
  "sku": "A-1",
  "quantity": 3,
  "price": 2.5
}
```

## Elide annotations in Kotlin

Marks an interface with `@API` and a method with `@Delicate`, which callers must opt in to. Kotlin projects get
`dev.elide.annotations` on the classpath; see [Elide annotations](https://elide.help/docs/api-jvm-annotations).

```pkl
// elide.pkl
amends "elide:project.pkl"

name = "cache"

jvm {
  main = "MainKt"
}
```

```kotlin
// src/main/kotlin/Main.kt
import dev.elide.annotations.API
import dev.elide.annotations.Delicate

@API
interface Cache {
  fun get(key: String): String?
  fun put(key: String, value: String)
}

class MemoryCache : Cache {
  private val entries = mutableMapOf<String, String>()

  override fun get(key: String) = entries[key]

  override fun put(key: String, value: String) {
    entries[key] = value
  }

  @Delicate
  fun clear() = entries.clear()
}

@OptIn(Delicate::class)
fun main() {
  val cache = MemoryCache()
  cache.put("user:1", "Ada")
  println(cache.get("user:1"))
  cache.clear()
  println(cache.get("user:1"))
  println(Cache::class.java.isAnnotationPresent(API::class.java))
}
```

```bash
elide run
```

```text
Ada
null
true
```

Without `@OptIn(Delicate::class)`, the build fails with `This API is marked delicate; opt in with
@OptIn(Delicate::class) if you understand its caveats.`

## Python calling JavaScript

Needs the Python component and `--interop`.

```python
# interop.py
from elide import js

total = js("[1, 2, 3, 4].reduce((a, b) => a + b, 0)")
print(total)
```

```bash
elide --interop python interop.py
```

```text
10
```

## JavaScript importing Python

Needs the Python component and `--interop`.

```python
# greet.py
def hello():
    return "Hello from Python"
```

```javascript
// main.mjs
import greet from "./greet.py";
console.log(greet.hello());
```

```bash
elide --interop run main.mjs
```

```text
Hello from Python
```

## WebAssembly from JavaScript

Builds a WebAssembly library from C with `zig`, then imports its exports as an ES module. Needs `zig` to build the `.wasm` file.

```c
// checksum.c
unsigned int adler32(const unsigned char *data, unsigned int len) {
  unsigned int a = 1, b = 0;
  for (unsigned int i = 0; i < len; i++) {
    a = (a + data[i]) % 65521;
    b = (b + a) % 65521;
  }
  return (b << 16) | a;
}
```

```javascript
// main.mjs
import { adler32, memory } from "./checksum.wasm";

const input = new TextEncoder().encode("Wikipedia");
new Uint8Array(memory.buffer).set(input, 1024);
console.log(adler32(1024, input.length).toString(16));
```

```bash
zig cc --target=wasm32-freestanding -O2 -nostdlib -Wl,--no-entry -Wl,--export=adler32 -o checksum.wasm checksum.c
elide run main.mjs
```

```text
11e60398
```

## WASI command

Builds a WASI command from C with `zig` and runs it with arguments. Needs `zig` to build the `.wasm` file.

```c
// wc.c
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
  int chars = 0;
  for (int i = 1; i < argc; i++) {
    chars += strlen(argv[i]);
    printf("%d: %s\n", i, argv[i]);
  }
  printf("%d words, %d characters\n", argc - 1, chars);
  return 0;
}
```

```bash
zig cc --target=wasm32-wasi -O2 -o wc.wasm wc.c
elide run wc.wasm -- polyglot runtime toolchain
```

```text
1: polyglot
2: runtime
3: toolchain
3 words, 24 characters
```

## Python script

Python's standard library runs with no virtual environment. Needs the Python component (`elide setup python`).

```python
# words.py
import json
import re
from collections import Counter
from dataclasses import asdict, dataclass

@dataclass
class Report:
    words: int
    unique: int
    top: list[tuple[str, int]]

text = """Elide runs Python, JavaScript and TypeScript.
Python runs without a separate interpreter; JavaScript runs too."""

words = re.findall(r"[a-z]+", text.lower())
report = Report(len(words), len(set(words)), Counter(words).most_common(3))
print(json.dumps(asdict(report)))
```

```bash
elide python words.py
```

```text
{"words": 15, "unique": 11, "top": [["runs", 3], ["python", 2], ["javascript", 2]]}
```

## PostgreSQL queries

A prepared batch insert, a transaction and an aggregate query with `elide:postgres`. Start a server first, for example
`docker run -d -e POSTGRES_USER=app -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=app -p 127.0.0.1:5432:5432 postgres:17`.

```ts
// orders.ts
import { Database } from "elide:postgres";

const db = await Database.connect(process.env.DATABASE_URL!);

await db.exec("DROP TABLE IF EXISTS orders");
await db.exec("CREATE TABLE orders (id SERIAL PRIMARY KEY, customer TEXT NOT NULL, total NUMERIC(10, 2))");

const insert = await db.prepare("INSERT INTO orders (customer, total) VALUES ($1, $2)");
await insert.executeBatch([["ada", 42.5], ["grace", 18], ["ada", 7.25]]);
await insert.close();

await db.transaction(async (tx) => {
  await tx.exec("UPDATE orders SET total = total * 0.9 WHERE customer = $1", "ada");
});

const result = await db.query(
  "SELECT customer, count(*)::int AS orders, sum(total)::float AS spent FROM orders GROUP BY customer ORDER BY customer",
);
for (const row of await result.all()) console.log(row);

await db.close();
```

```bash
DATABASE_URL=postgresql://app:secret@127.0.0.1:5432/app elide run orders.ts
```

```text
{customer: "ada", orders: 2, spent: 44.78}
{customer: "grace", orders: 1, spent: 18}
```

## Server-sent events

A `ReadableStream` body streams events as they are produced; `request.signal` stops the timer when the client leaves.

```ts
// events.ts
const encoder = new TextEncoder();

Elide.serve({
  hostname: "127.0.0.1",
  port: 3000,
  fetch(request) {
    let timer: ReturnType<typeof setInterval>;
    const body = new ReadableStream({
      start(controller) {
        let n = 0;
        timer = setInterval(() => {
          n += 1;
          controller.enqueue(encoder.encode(`event: tick\ndata: ${n}\n\n`));
          if (n === 3) {
            clearInterval(timer);
            controller.close();
          }
        }, 500);
        request.signal.addEventListener("abort", () => clearInterval(timer));
      },
    });
    return new Response(body, {
      headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache" },
    });
  },
});
```

```bash
elide run events.ts
curl -N http://127.0.0.1:3000/
```

```text
event: tick
data: 1

event: tick
data: 2

event: tick
data: 3
```

Each event arrives half a second after the previous one.

## Request limits

`maxBodyBytes` rejects large request bodies before the handler reads them.

```js
// limits.mjs
const server = Elide.serve({
  hostname: "127.0.0.1",
  port: 0,
  maxBodyBytes: 1024,
  async fetch(request) {
    const body = await request.text();
    return new Response(`received ${body.length} bytes\n`);
  },
});
setTimeout(async () => {
  for (const size of [512, 4096]) {
    const res = await fetch(`http://127.0.0.1:${server.port}/`, { method: "POST", body: "x".repeat(size) });
    console.log(size, res.status, (await res.text()).trim());
  }
  server.close();
}, 0);
```

```bash
elide run limits.mjs
```

```text
512 200 received 512 bytes
4096 413 Payload Too Large
```

## node:http server and client

```js
// http.mjs
import http from "node:http";

const server = http.createServer((req, res) => {
  let body = "";
  req.on("data", (chunk) => (body += chunk));
  req.on("end", () => {
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ method: req.method, url: req.url, received: body.length }));
  });
});

server.listen(0, "127.0.0.1", () => {
  const { port } = server.address();
  const req = http.request({ port, host: "127.0.0.1", method: "POST", path: "/items" }, (res) => {
    let data = "";
    res.setEncoding("utf8");
    res.on("data", (chunk) => (data += chunk));
    res.on("end", () => {
      console.log(res.statusCode, res.headers["content-type"]);
      console.log(data);
      server.close();
    });
  });
  req.end("hello");
});
```

```bash
elide run http.mjs
```

```text
200 application/json
{"method":"POST","url":"/items","received":5}
```

## Sandboxed subprocess

`--allow-run` lists the commands a program may start; any other command fails.

```js
// spawn.mjs
import { execFileSync } from "node:child_process";

console.log(execFileSync("echo", ["allowed"], { encoding: "utf8" }).trim());
try {
  execFileSync("ls", ["/"]);
} catch (e) {
  console.log(e.message);
}
```

```bash
elide --allow-run=echo run spawn.mjs
```

```text
allowed
spawn of 'ls' is not permitted; grant it with --allow-run=ls
```

## Sign data with Web Crypto

```ts
// sign.ts
const { privateKey, publicKey } = await crypto.subtle.generateKey(
  { name: "ECDSA", namedCurve: "P-256" },
  true,
  ["sign", "verify"],
);

const message = new TextEncoder().encode("ship order 1042");
const algorithm = { name: "ECDSA", hash: "SHA-256" };
const signature = await crypto.subtle.sign(algorithm, privateKey, message);

console.log("signature bytes:", signature.byteLength);
console.log("valid:", await crypto.subtle.verify(algorithm, publicKey, signature, message));

const tampered = new TextEncoder().encode("ship order 9999");
console.log("tampered valid:", await crypto.subtle.verify(algorithm, publicKey, signature, tampered));

const jwk = await crypto.subtle.exportKey("jwk", publicKey);
console.log("public key:", jwk.kty, jwk.crv);
```

```bash
elide run sign.ts
```

```text
signature bytes: 64
valid: true
tampered valid: false
public key: EC P-256
```

## Gzip with CompressionStream

```ts
// gzip.ts
const text = "elide ".repeat(1000);

const compressed = await new Response(
  new Blob([text]).stream().pipeThrough(new CompressionStream("gzip")),
).arrayBuffer();

const restored = await new Response(
  new Blob([compressed]).stream().pipeThrough(new DecompressionStream("gzip")),
).text();

console.log(`original: ${text.length} bytes`);
console.log(`gzip: ${compressed.byteLength} bytes`);
console.log(`round trip: ${restored === text}`);
```

```bash
elide run gzip.ts
```

```text
original: 6000 bytes
gzip: 73 bytes
round trip: true
```

## Dates with Temporal

Month arithmetic clamps to the end of the month, and zoned times keep their wall-clock time across a daylight-saving
change.

```ts
// dates.ts
const start = Temporal.PlainDate.from("2026-01-30");
console.log(start.add({ months: 1 }).toString());

const meeting = Temporal.ZonedDateTime.from("2026-03-28T09:00[Europe/London]");
console.log(meeting.add({ days: 1 }).toString());
console.log(meeting.withTimeZone("America/New_York").toPlainTime().toString());

const due = Temporal.PlainDate.from("2026-12-25");
console.log(start.until(due, { largestUnit: "months" }).toString());
```

```bash
elide run dates.ts
```

```text
2026-02-28
2026-03-29T09:00:00+01:00[Europe/London]
05:00:00
P10M25D
```

## Limit workers

`--limit=workers=N` caps live workers; one more throws `ERR_WORKER_LIMIT`.

```js
// workers.mjs
import { Worker } from "node:worker_threads";

const source = "setInterval(() => {}, 1000)"; // stays alive until terminated
const workers = [];
for (let i = 1; i <= 3; i++) {
  try {
    workers.push(new Worker(source, { eval: true }));
    console.log(`worker ${i} started`);
  } catch (e) {
    console.log(`worker ${i}: ${e.code}`);
  }
}
await Promise.all(workers.map((w) => w.terminate()));
```

```bash
elide --limit=workers=2 run workers.mjs
```

```text
worker 1 started
worker 2 started
worker 3: ERR_WORKER_LIMIT
```

## Filter tests with CEL

`--where` selects tests with a [CEL](https://elide.help/docs/api-cel) expression over `name`, `parents` and `file`.

```ts
// cart.test.ts
import { describe, test } from "node:test";
import assert from "node:assert/strict";

describe("cart", () => {
  test("adds items", () => assert.equal([1, 2].length, 2));
  test("applies discount [slow]", () => assert.equal(Math.round(10 * 0.9), 9));
});

describe("checkout", () => {
  test("charges card", () => assert.ok(true));
  test("sends receipt [slow]", () => assert.ok(true));
});
```

```bash
elide test --where 'name.endsWith("[slow]")'
```

```text
cart.test.ts
⇥ cart > adds items
✓ cart > applies discount [slow] [1ms]
⇥ checkout > charges card
✓ checkout > sends receipt [slow] [3ms]

 2 pass
 2 skip
 0 fail
Ran 4 tests across one file. (0.14s)
```

## JUnit XML in CI

`--reporter junit` writes one XML file per test file for CI test-report steps; a failure exits `1`.

```ts
// price.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";

const total = (items: number[]) => items.reduce((a, b) => a + b, 0);

test("sums prices", () => assert.equal(total([2, 3]), 5));
test("empty cart", () => assert.equal(total([]), 1));
```

```bash
elide test --reporter junit --reporter-outfile reports
```

```text
 1 pass
 0 skip
 1 fail
Ran 2 tests across one file. (0.11s)
```

`reports/js/TEST-price.test.ts.xml`:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="price.test.ts" tests="2" failures="1" errors="0" skipped="0" time="0.026">
  <testcase name="sums prices" classname="price.test.ts" time="0.005"/>
  <testcase name="empty cart" classname="price.test.ts" time="0.021">
    <failure message="Expected values to be strictly equal:&#10;&#10;0 !== 1&#10;" type="ERR_ASSERTION">…</failure>
  </testcase>
</testsuite>
```

## Multi-context server

`--contexts=auto` runs one copy of the module per core (Linux). Each copy keeps its own globals, so the counter counts
per context.

```ts
// counter.ts
const id = crypto.randomUUID().slice(0, 8);
let count = 0;

export default {
  fetch(): Response {
    count += 1;
    return Response.json({ context: id, count });
  },
};
```

```bash
elide serve --no-tui --contexts=auto --port 8080 counter.ts
for i in 1 2 3 4; do curl -s http://127.0.0.1:8080/; echo; done
```

```text
{"context":"60cf3464","count":1}
{"context":"60e90376","count":1}
{"context":"90086101","count":1}
{"context":"4adfe8e1","count":1}
```

Each `curl` opens a new connection, which the server may hand to any context.

## Custom span in TypeScript

Spans from `@opentelemetry/api`, exported by Elide with no SDK installed. `using` ends the inner span with its block.
Start a local collector first: `docker run --rm -p 4318:4318 otel/opentelemetry-collector:0.115.1`.

```ts
// checkout.ts
import { trace } from "@opentelemetry/api";
import { currentSpanContext, flush } from "elide:telemetry";

const tracer = trace.getTracer("checkout");

async function chargeCard(amount: number): Promise<void> {
  using span = tracer.startSpan("charge card");
  span.setAttribute("payment.amount", amount);
  await new Promise((resolve) => setTimeout(resolve, 20));
}

await tracer.startActiveSpan("checkout", async (span) => {
  span.setAttribute("order.id", 42);
  await chargeCard(19.99);
  console.log("charged order 42, sampled:", currentSpanContext()?.traceFlags === 1);
  span.end();
});

console.log("exported:", await flush());
```

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_SERVICE_NAME=checkout elide run checkout.ts
```

```text
charged order 42, sampled: true
exported: true
```

The collector receives `checkout` with its child `charge card`, and the `console.log` line as a log record with
their trace id.

## Metrics instruments

A counter, a histogram with explicit buckets, and an observable gauge.

```ts
// metrics.ts
import { metrics } from "@opentelemetry/api";
import { flush } from "elide:telemetry";

const meter = metrics.getMeter("shop");
const orders = meter.createCounter("shop.orders", { unit: "{order}" });
const latency = meter.createHistogram("shop.charge.duration", {
  unit: "s",
  advice: { explicitBucketBoundaries: [0.05, 0.1, 0.25, 0.5] },
});
const queue: string[] = ["a", "b"];
meter
  .createObservableGauge("shop.queue.depth", { unit: "{job}" })
  .addCallback((result) => result.observe(queue.length));

for (const [region, seconds] of [["eu", 0.08], ["us", 0.21], ["eu", 0.04]] as const) {
  orders.add(1, { region });
  latency.record(seconds, { region });
}

console.log("exported:", await flush());
```

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_SERVICE_NAME=shop elide run metrics.ts
```

```text
exported: true
```

The collector's debug output, trimmed:

```text
InstrumentationScope shop
     -> Name: shop.orders
Data point attributes:
     -> region: Str(eu)
Value: 2.000000
     -> Name: shop.charge.duration
Data point attributes:
     -> region: Str(eu)
Count: 2
Sum: 0.120000
     -> Name: shop.queue.depth
Value: 2.000000
```

## Python span and logging

Needs the Python component. `logging` output is exported as log records with the span's ids; no
`opentelemetry` package is needed.

```python
# orders.py
import logging

import elide.telemetry
from opentelemetry import trace

logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
log = logging.getLogger("orders")
tracer = trace.get_tracer("orders")

with tracer.start_as_current_span("import orders") as span:
    span.set_attribute("orders.count", 3)
    log.info("imported %d orders", 3)
    print("sampled:", elide.telemetry.current_span_context()["trace_flags"] == 1)

print("exported:", elide.telemetry.flush())
```

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_SERVICE_NAME=orders elide python orders.py
```

```text
INFO orders: imported 3 orders
sampled: True
exported: True
```

## OTLP to a local collector

A served handler continues the caller's trace: the server span takes the `traceparent` parent, and the handler's own
span is its child.

```ts
// server.ts
import { trace } from "@opentelemetry/api";

const tracer = trace.getTracer("inventory");

export default {
  async fetch(request: Request): Promise<Response> {
    const id = new URL(request.url).pathname.split("/").pop() ?? "";
    return tracer.startActiveSpan("load item", async (span) => {
      span.setAttribute("item.id", id);
      span.end();
      return Response.json({ id, stock: 7 });
    });
  },
};
```

```bash
docker run --rm -d -p 4317:4317 -p 4318:4318 otel/opentelemetry-collector:0.115.1
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_SERVICE_NAME=inventory elide serve server.ts
curl -H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01' http://localhost:8080/items/17
```

```text
{"id":"17","stock":7}
```

The collector's debug output, trimmed:

```text
InstrumentationScope inventory
    Trace ID       : 4bf92f3577b34da6a3ce929d0e0e4736
    Parent ID      : 6a28bf795e58acfb
    Name           : load item
     -> item.id: Str(17)
InstrumentationScope dev.elide.runtime 1.6.0
    Trace ID       : 4bf92f3577b34da6a3ce929d0e0e4736
    Parent ID      : 00f067aa0ba902b7
    ID             : 6a28bf795e58acfb
    Name           : GET
    Kind           : Server
     -> url.path: Str(/items/17)
     -> http.response.status_code: Int(200)
     -> Name: http.server.request.duration
Exemplar #0
     -> Trace ID: 4bf92f3577b34da6a3ce929d0e0e4736
     -> Span ID: 6a28bf795e58acfb
```

## Baggage across services

Elide's server ignores an incoming `baggage` header until inbound baggage is on, and then admits only allowed keys.

```ts
// server.ts
import { context, propagation } from "@opentelemetry/api";

export default {
  async fetch(): Promise<Response> {
    const baggage = propagation.getBaggage(context.active());
    const tenant = baggage?.getEntry("tenant")?.value ?? "none";
    const debug = baggage?.getEntry("debug")?.value ?? "none";
    return new Response(`tenant=${tenant} debug=${debug}\n`);
  },
};
```

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
ELIDE_OTEL_BAGGAGE_INBOUND=true ELIDE_OTEL_BAGGAGE_ALLOW=tenant \
elide serve server.ts
curl -H 'baggage: tenant=acme,debug=true' http://localhost:8080/
```

```text
tenant=acme debug=none
```

Without `ELIDE_OTEL_BAGGAGE_INBOUND=true`, the response is `tenant=none debug=none`.
