Persistence (Advanced)
- Overview
- Quick Start
- Providers
- Harnesses
- Harness Auth
- Workspace
- Tools
- Policy
- Lifecycle & Snapshots
- Portable Snapshots
- Keep Files After Reload
- Save a Named Version
- Branch From a Version
- Send a Frozen File
- Let the Agent Save and Fork
- Pick Which Files to Keep
- What a Snapshot Stores
- Instance Durability
- Durable Runs
- Events
Sandboxes (Advanced)
React Native
Your native app calls your own backend, not a same-origin browser route. Use useChat from @tanstack/ai-react with an XHR adapter and an absolute URL.
1. Set the backend URL#
const baseUrl =
process.env.EXPO_PUBLIC_TANSTACK_AI_BASE_URL ??
'http://127.0.0.1:8787'
const httpUrl = `${baseUrl}/chat/http`
const sseUrl = `${baseUrl}/chat/sse`Use a URL that your runtime can reach:
- iOS simulator: usually localhost or 127.0.0.1.
- Android emulator: usually 10.0.2.2, to reach the host machine.
- A physical device: a LAN URL or a tunnel URL.
2. Connect with xhrHttpStream#
Use xhrHttpStream() for Expo and React Native. It reads newline-delimited JSON from incremental XHR progress events. Your server returns the stream with toHttpResponse() (see HTTP Stream):
import { useChat, xhrHttpStream } from "@tanstack/ai-react";
const baseUrl = process.env.EXPO_PUBLIC_TANSTACK_AI_BASE_URL ?? 'http://127.0.0.1:8787';
const httpUrl = `${baseUrl}/chat/http`;
const chat = useChat({
connection: xhrHttpStream(httpUrl),
});Mobile connections drop often. If the server adds a durability adapter, both XHR adapters reconnect and support joinRun. See Resumable Streams.
Use SSE on mobile#
If your server returns text/event-stream with toServerSentEventsResponse() (see Server-Sent Events), use xhrServerSentEvents():
import { useChat, xhrServerSentEvents } from "@tanstack/ai-react";
const baseUrl = process.env.EXPO_PUBLIC_TANSTACK_AI_BASE_URL ?? 'http://127.0.0.1:8787';
const sseUrl = `${baseUrl}/chat/sse`;
const chat = useChat({
connection: xhrServerSentEvents(sseUrl),
});Use fetchHttpStream on mobile#
fetchHttpStream() works only if your React Native runtime has all of these:
- Streaming fetch responses.
- Response.body.getReader().
- TextDecoder.
The server still returns newline-delimited JSON with toHttpResponse():
import { useChat, fetchHttpStream } from "@tanstack/ai-react";
const baseUrl = process.env.EXPO_PUBLIC_TANSTACK_AI_BASE_URL ?? 'http://127.0.0.1:8787';
const httpUrl = `${baseUrl}/chat/http`;
const chat = useChat({
connection: fetchHttpStream(httpUrl),
});If one of these APIs is missing, fetchHttpStream() throws UnsupportedResponseStreamError. A polyfill that buffers the response does not help, because the adapter needs incremental bytes. Use xhrHttpStream() or xhrServerSentEvents().
Keep the bundle small#
Keep provider SDKs and server helpers on your backend. Import only hooks and connection adapters in the React Native bundle. Do not import these:
- OpenAI, Anthropic, or Gemini SDKs.
- React DOM UI or devtools UI.
- Packages for other frameworks.
For a full mobile walkthrough, see Quick Start: React Native.
Send a message from the simulator. The reply streams into chat.messages as the model writes it.