| name | getting-started |
| description | First-time setup for Durable Streams. Install @durable-streams/client, create a stream with DurableStream.create(), read with stream(), subscribe to live updates, resume from saved offsets. Covers offset semantics ("-1", "now", opaque tokens), LiveMode (false, true, "long-poll", "sse"), and StreamResponse consumption (.json(), .text(), .subscribeJson()).
|
| type | lifecycle |
| library | durable-streams |
| library_version | 0.2.1 |
| sources | ["durable-streams/durable-streams:README.md","durable-streams/durable-streams:packages/client/src/stream-api.ts","durable-streams/durable-streams:packages/client/src/stream.ts"] |
Durable Streams — Getting Started
Durable Streams is an HTTP-based protocol for persistent, resumable, append-only
event streams. Use stream() for reading and DurableStream when you also need
to create or write to streams.
Setup
import { stream, DurableStream } from "@durable-streams/client"
const handle = await DurableStream.create({
url: "https://your-server.com/v1/stream/my-stream",
contentType: "application/json",
})
await handle.append(JSON.stringify({ event: "user.created", userId: "123" }))
await handle.append(JSON.stringify({ event: "user.updated", userId: "123" }))
const res = await stream({
url: "https://your-server.com/v1/stream/my-stream",
offset: "-1",
live: false,
})
const items = await res.json()
Core Patterns
Read all existing data (catch-up)
import { stream } from "@durable-streams/client"
const res = await stream({
url: "https://your-server.com/v1/stream/my-stream",
offset: "-1",
live: false,
})
const data = await res.json()
const savedOffset = res.offset
Subscribe to live updates
import { stream } from "@durable-streams/client"
const res = await stream({
url: "https://your-server.com/v1/stream/my-stream",
offset: "-1",
live: true,
})
res.subscribeJson(async (batch) => {
for (const item of batch.items) {
console.log("Received:", item)
}
saveCheckpoint(batch.offset)
})
Resume from a saved offset
import { stream } from "@durable-streams/client"
const savedOffset = loadCheckpoint()
const res = await stream({
url: "https://your-server.com/v1/stream/my-stream",
offset: savedOffset,
live: true,
})
res.subscribeJson(async (batch) => {
for (const item of batch.items) {
processItem(item)
}
saveCheckpoint(batch.offset)
})
Create and write to a stream
import { DurableStream, IdempotentProducer } from "@durable-streams/client"
const handle = await DurableStream.create({
url: "https://your-server.com/v1/stream/my-stream",
contentType: "application/json",
})
await handle.append(JSON.stringify({ event: "hello" }))
const producer = new IdempotentProducer(handle, "my-service", {
autoClaim: true,
onError: (err) => console.error("Write failed:", err),
})
producer.append(JSON.stringify({ event: "world" }))
await producer.flush()
await producer.close()
Common Mistakes
CRITICAL Parsing or constructing offsets manually
Wrong:
const nextOffset = `${parseInt(offset.split("_")[0]) + 1}_0`
Correct:
const nextOffset = response.offset
Offsets are opaque tokens. The internal format is an implementation detail that may change between server versions.
Source: PROTOCOL.md section 6 (Offsets)
CRITICAL Using offset 0 instead of "-1" for stream start
Wrong:
const res = await stream({ url, offset: "0" })
Correct:
const res = await stream({ url, offset: "-1" })
The special start-of-stream offset is the string "-1", not "0". Using "0" may miss data or return 400.
Source: README.md offset semantics section
HIGH Calling multiple consumption methods on same response
Wrong:
const res = await stream({ url, offset: "-1" })
const data = await res.json()
res.subscribeJson((batch) => {
})
Correct:
const res = await stream({ url, offset: "-1", live: true })
res.subscribeJson((batch) => {
for (const item of batch.items) {
}
})
StreamResponse enforces single consumption. Choose one consumption method per response.
Source: packages/client/src/response.ts
HIGH Setting live mode for one-shot reads
Wrong:
const res = await stream({ url, offset: "-1", live: true })
const data = await res.json()
Correct:
const res = await stream({ url, offset: "-1", live: false })
const data = await res.json()
Use live: false for catch-up reads. live: true keeps the connection open waiting for new data.
Source: packages/client/src/types.ts LiveMode type
See also
Note: Streams must be created with DurableStream.create() before they can be read. See the writing-data skill for stream creation.
Version
Targets @durable-streams/client v0.2.1.