Migration: RetainDBClient to RetainDB
Move from the older RetainDBClient module-based SDK to the new simple RetainDB class.
RetainDBClient is deprecated. RetainDB is the current interface — simpler, less to configure, and the pattern all new docs assume.
What changed
The old SDK had six named modules (memory, session, analytics, profile, sources, queue) that you called directly. The new SDK has one fluent chain: db.user(id).
// Before (deprecated)
import { RetainDBClient } from "@retaindb/sdk";
const client = RetainDBClient.fromEnv();
await client.memory.add({
user_id: "user-123",
content: "Prefers short answers",
memory_type: "preference",
});
const results = await client.memory.search({
user_id: "user-123",
query: "How to respond?",
include_pending: true,
top_k: 5,
});
await client.queue.flush();
await client.shutdown();// After (current)
import { RetainDB } from "@retaindb/sdk";
const db = new RetainDB({ apiKey: process.env.RETAINDB_KEY });
await db.user("user-123").remember("Prefers short answers");
const { context } = await db.user("user-123").getContext("How to respond?");
// No flush needed — auto-drains on process exitMigration map
| Old | New |
|---|---|
RetainDBClient.fromEnv() | new RetainDB({ apiKey: process.env.RETAINDB_KEY }) |
client.memory.add({ user_id, content }) | db.user(userId).remember(content) |
client.memory.search({ user_id, query }) | db.user(userId).getContext(query) |
client.memory.delete(id) | db.user(userId).forget(id) |
client.withRunContext({ userId, sessionId }) | db.user(userId).session(sessionId) |
client.queue.flush() + client.shutdown() | Not needed (auto-drains) |
RETAINDB_API_KEY env var | RETAINDB_KEY env var |
The full-turn pattern (new)
If you were doing retrieve → call LLM → store manually, replace it with runTurn:
// Before
const results = await client.memory.search({ user_id, query: lastMessage, top_k: 5 });
const context = results.results.map(r => r.memory.content).join("\n");
const reply = await llm.chat({ system: context, messages });
await client.memory.addBulk({ memories: messages.map(m => ({ user_id, content: m.content })) });
// After
const { response } = await db.user(userId).runTurn({
messages,
generate: (ctx) => llm.chat(ctx),
});Environment variable
The new SDK reads RETAINDB_KEY by default. RETAINDB_API_KEY still works as a fallback.
# New (preferred)
export RETAINDB_KEY="rdb_..."
# Old (still works)
export RETAINDB_API_KEY="rdb_..."Project defaulting
You no longer need to set RETAINDB_PROJECT. If no project is configured, the SDK uses default — auto-created on first use.
If you want an explicit project:
export RETAINDB_PROJECT="my-app"Safe migration order
- Swap
RetainDBClient.fromEnv()→new RetainDB({ apiKey: ... }) - Replace one
client.memory.add+client.memory.searchpair withrunTurn - Verify the response contains context from previous conversations
- Remove manual
flush()/shutdown()calls - Migrate the rest of your code
Next step
- SDK Quickstart — starting fresh
- User and Session Scoping — the
db.user(id)chain
Was this page helpful?
Your feedback helps us prioritize docs improvements weekly.