Browser and React Native
Use the portable client entry point in browser, Expo, and React Native applications
Use the portable /client entry point in browser, Expo, and React Native applications. It includes the cloud and remote transports without importing Node process-management modules:
import { LettaAgentClient } from "@letta-ai/letta-agent-sdk/client";
const client = new LettaAgentClient({ backend: "cloud", apiKey: userProvidedApiKey, webSocketAuth: "query",});What the portable entry supports
Section titled “What the portable entry supports”| Capability | Portable /client entry | Node package root |
|---|---|---|
backend: "cloud" | ✅ | ✅ |
backend: "remote" | ✅ | ✅ |
backend: "local" | ❌ | ✅ |
MCP servers (mcpServers) | ❌ | ✅ |
Client tools (tools) | ✅ | ✅ |
Repositories (client.repositories) | ✅ | ✅ |
imageFromFile helper | ❌ (use imageFromBase64) | ✅ |
Import from the package root in Node.js when you need backend: "local", which starts and manages a local App Server subprocess, or MCP servers, which run in the SDK’s Node process.
Browser authentication
Section titled “Browser authentication”Browser WebSockets cannot set upgrade headers, so cloud clients in the browser should use webSocketAuth: "query" to send credentials in the connection URL instead:
const client = new LettaAgentClient({ backend: "cloud", apiKey: userProvidedApiKey, webSocketAuth: "query",});React Native
Section titled “React Native”For an authenticated remote App Server in React Native, adapt the platform WebSocket constructor so the SDK can pass the Authorization header:
import { LettaAgentClient, createReactNativeWebSocketConstructor,} from "@letta-ai/letta-agent-sdk/client";
const client = new LettaAgentClient({ backend: "remote", url: appServerUrl, authToken: appServerToken, WebSocket: createReactNativeWebSocketConstructor(WebSocket),});Sending messages from portable clients
Section titled “Sending messages from portable clients”Sessions work the same as in Node: create or resume a session, send, and stream. See Sending messages for the full event-handling patterns.
await using session = client.resumeSession(agentId);
await session.send("Summarize my unread updates.");
for await (const message of session.stream()) { if (message.type === "assistant") process.stdout.write(message.content);}For images, use imageFromBase64 or imageFromURL; the file-reading helper is Node-only.