Skip to main content
S2 integrates with TanStack AI through the @s2-dev/resumable-stream/tanstack-ai entrypoint. The server helper stores TanStack StreamChunk events in S2. The client helper builds a TanStack SubscribeConnectionAdapter so useChat can send messages normally while reading assistant chunks from an S2 replay stream.

Install

If you use TanStack’s OpenAI adapter:
Create a basin with Create Stream on Append and Create Stream on Read enabled.

Server Setup

lib/s2.ts

Start A Turn

app/api/chat/route.ts

Replay Route

app/api/chat/replay/route.ts
Use live: true for session-mode chat UIs so the replay connection stays open at the tail and receives future turns.

Client

app/page.tsx
Every replayed chunk includes an SSE id: cursor. createConnection remembers the most recent cursor inside that connection instance and sends it back as from on the next subscribe request, so a dropped subscription can continue after the chunks already delivered instead of rendering them twice. For a full page refresh, pass the saved history cursor as shown below.

Completed History

TanStack useChat expects completed messages as app state, so keep transcript loading in your app:
  1. Fetch history before mounting useChat.
  2. Pass it as initialMessages.
  3. Start replay from the history cursor so old chunks are not rendered again.
The runnable example stores periodic message snapshots in the same session stream and exposes a /history route. That history behavior is intentionally example code, not package API.

Options

createResumableChat accepts: createConnection accepts:

Example

A complete TanStack Start chat app is available here: examples/tanstack-ai-chat.