s2-sdk-typescript

The official TypeScript SDK for S2's durable streams API - append, read, and tail records with typed, retryable sessions.

SDK
npm
v0.26.0
35stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
69/100Good
Development Activity100
Maintenance100
Community24
Maturity32
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture85
Code Quality88
Innovation78
Learning Curve80

@s2-dev/streamstore is the official TypeScript client for S2, a serverless, managed data store built specifically for durable, unlimited streams. Rather than wrapping a generic database, the SDK models S2’s own primitives directly: accounts own basins (namespaces), basins own streams, and streams are append-only logs that can be written to, read from by sequence number or timestamp, and tailed live for new records.

The SDK layers ergonomic, high-level constructs on top of S2’s REST API: an AppendSession for ordered, pipelined writes with backpressure; a Producer with automatic request batching and lingering for high-throughput producers; and readSession for streaming reads that can follow a stream’s tail indefinitely. It ships configurable retry policies (including an idempotency-aware policy for safe replays), automatic transport selection between fetch-based HTTP/1.1 and an HTTP/2 streaming transport (s2s), and works across Node.js, Bun, Deno, and browsers.

It is a thin, well-typed layer purpose-built for one service - not a general message-queue or database client - so every abstraction (basins, streams, append acknowledgements, caught-up tracking) maps directly onto an S2 concept.

What You Get

  • Full client surface - S2 top-level client plus scoped helpers for basins, streams, access tokens, locations, and metrics.
  • AppendSession - a stateful, ordered append channel with backpressure via maxInflightBytes, returning tickets you can await for durability acknowledgements.
  • Producer with auto-batching - Producer + BatchTransform linger and coalesce records into larger batches automatically for high-throughput writers.
  • Read sessions with live tailing - readSession supports async iteration, sequence/timestamp-based starts, and open-ended following of new records.
  • Configurable retries - global RetryConfig with appendRetryPolicy: "noSideEffects" | "all" to control whether retries can duplicate non-idempotent appends.
  • Dual transport with HTTP/2 pooling - automatic detection between fetch (HTTP/1.1) and s2s (HTTP/2), with connection pooling and flow-control handling for the streaming transport.

Common Use Cases

  • High-throughput event ingestion - using Producer to batch and append large volumes of events durably with minimal per-record overhead.
  • Ordered write pipelines - using AppendSession where downstream consumers depend on the exact order records were submitted.
  • Live tailing consumers - opening a readSession with an open-ended stop condition to process new records as they land.
  • Point-in-time or replay reads - reading from a specific sequence number or timestamp to reprocess a range of a stream’s history.
  • Cross-runtime streaming clients - shipping the same SDK code to a Node/Bun backend and a browser client, relying on automatic transport fallback.

Under The Hood

Architecture The client is organized around S2’s own domain model: S2 is the account-level entrypoint composing S2Basins, S2AccessTokens, S2Locations, and S2Metrics; calling .basin() yields an S2Basin scoped to basin-level operations, and .stream() on that yields an S2Stream for data-plane appends and reads (packages/streamstore/src/s2.ts, basin.ts, stream.ts). Data-plane primitives are layered rather than flat: raw append/read calls sit underneath higher-level AppendSession/Producer and readSession abstractions (producer.ts, batch-transform.ts) that add ordering, batching, and backpressure without changing the underlying wire protocol. A generated client layer (src/generated/client, src/generated/proto) isolates REST/protobuf codegen from the hand-written ergonomic API, so regenerating from S2’s OpenAPI/proto specs does not touch the public surface directly.

Tech Stack Written in TypeScript, built with tsc into separate ESM and CJS outputs and verified with @arethetypeswrong/cli for package-export correctness. Runtime dependencies are minimal - @protobuf-ts/runtime for the binary protocol path and debug for diagnostic logging - keeping the installed footprint small. The monorepo (managed with Bun workspaces and Changesets for release versioning) also houses companion packages (patterns, resumable-stream) and generates its REST client via @hey-api/openapi-ts and its protobuf bindings via @protobuf-ts/plugin, with deno.json/deno.lock present for explicit Deno compatibility testing.

Code Quality The package has an extensive Vitest test suite covering unit behavior (retry policies, batching, session state machines, error classification) and end-to-end scenarios (*.e2e.test.ts against a live or emulated S2 backend), including targeted regression tests tied to specific numbered GitHub issues. Error handling is explicit and typed - error.ts classifies connection failures across Node, Chrome, Firefox, and Safari error message formats and normalizes them into a typed S2Error/retry-eligibility model rather than swallowing failures. The codebase is linted and formatted with Biome, uses strict TypeScript throughout, and CI configuration lives under .github/.

What Makes It Unique Unlike general-purpose queue or database SDKs, this client is built end-to-end around one narrow, well-defined service model - durable, unlimited append-only streams - which lets it offer stronger guarantees (ordering, caught-up tracking, idempotency-aware retries) than a generic wrapper could. Its dual-transport design, automatically choosing between a simple fetch-based path and a pooled HTTP/2 streaming transport with explicit flow-control handling, is a comparatively rare piece of engineering for a client SDK at this scale, and its cross-runtime support (Node, Bun, Deno, browsers) is validated directly in the test suite rather than assumed.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search