ai-core/client-persistence

Persist TanStack AI chat transcripts and generation state across browser reloads.

3.1k|316|Updated Oct 8, 2025
One-click install
npx skills add https://github.com/TanStack/ai --skill ai-core-client-persistence
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: ai-core/client-persistence
Source: https://github.com/TanStack/ai/tree/main/packages/ai/skills/ai-core/client-persistence
Command: npx skills add https://github.com/TanStack/ai --skill ai-core-client-persistence

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Chat UIs built with useChat or ChatClient lose their entire message history, pending tool approvals, and in-flight streams when the user reloads the page. This Skill explains how to persist chat state per threadId so reloads restore transcripts, pending interrupts, and mid-stream runs.

Core Features & Use Cases

  • Browser storage adapters: localStoragePersistence, sessionStoragePersistence, and indexedDBPersistence cache the full transcript client-side for SPA reload durability.
  • Server-authoritative mode: Setting persistence: true hydrates the thread from the server by threadId on mount, caching nothing in the browser — ideal for multi-device and compliance-sensitive apps.
  • Generation hook hydration: useGenerateImage, useGenerateVideo, and similar hooks restore status, result, and error for the last generation under a required threadId, with optional artifactUrl mapping to restore media bytes from your own origin.
  • Use Case: A support chat SPA where users frequently refresh the page — add localStoragePersistence() with a stable threadId so the full conversation and any pending approval UI survive every reload.

Quick Start

Add localStoragePersistence() as the persistence option on my useChat hook with a stable threadId so the chat transcript survives page reloads.

Frequently Asked Questions about ai-core/client-persistence

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I persist useChat messages across page reloads in React?

Pass a persistence adapter like localStoragePersistence() to the useChat persistence option along with a stable threadId. The adapter stores the full transcript per threadId, so a reload repaints the conversation and restores any pending interrupt.

localStorage vs IndexedDB vs server persistence for chat history?

localStoragePersistence is synchronous and survives restarts but is quota-bound; indexedDBPersistence handles larger data asynchronously; sessionStoragePersistence only survives same-tab reloads. For large transcripts, multi-device sync, or compliance, use persistence: true with a server store instead.

Does TanStack AI chat persistence work across multiple devices?

Client storage adapters like localStorage are per-browser, so they cannot sync across devices. Use server-authoritative mode (persistence: true) with withPersistence and a hydrate route on the server so any device can reload the thread by threadId.

Why is my chat empty after reload with persistence: true?

persistence: true caches nothing in the browser — it hydrates from the server by threadId on mount. If the server has no history for that threadId (no withPersistence or reconstructChat route), the chat loads empty.

Can a reload resume a chat response that was still streaming?

Only if the route uses delivery durability via toServerSentEventsResponse(stream, { durability: ... }). Persistence alone restores finished runs and pending interrupts; rejoining an in-flight stream requires the durable stream so the client can call joinRun.

Do generation hooks like useGenerateImage support browser storage adapters?

No. Generation hooks accept only persistence: true (boolean), which hydrates the last generation for a required threadId from the server on mount. Nothing is cached in the browser, and media bytes restore only if the server persists artifacts with an artifactUrl mapper.