@cratebase/client
v0.6.0
Published
First-party typed TypeScript SDK for Cratebase: records, auth (password/OTP/OAuth2/MFA, cookie sessions, impersonation, bans), realtime, files, batch, and admin APIs.
Readme
@cratebase/client
The first-party typed TypeScript SDK for Cratebase:
records, auth (password/OTP/magic-link/TOTP/OAuth2 (12 built-in presets + generic OIDC)/MFA,
linked accounts, cookie sessions, impersonation, bans), realtime, realtime channels + presence,
in-app/email/push notifications, files, batch, mail (_emailTemplates + sendRule), custom SQL
RPC, and admin APIs — plus the value-add surface (vector search, LLM chat, MCP tool schemas, the
durable job queue) built in, no separate package required.
A real generic Schema type parameter (paired with cratebase typegen), no positional-argument
ambiguity, no client-side request auto-cancellation to fight, and first-class coverage of every
Cratebase endpoint (sessions, bans, the server-driven OAuth2 redirect flow).
bun add @cratebase/clientimport { createClient } from "@cratebase/client";
const cb = createClient("http://localhost:8090");
const posts = await cb.collection("posts").list({ filter: "published = true", search: "treasure" });
const unsubscribe = await cb.collection("posts").subscribe("*", (e) => console.log(e.action, e.record));
await cb.auth.signIn.password({ identity: "[email protected]", password: "..." });Full documentation lives on the docs site under
TypeScript SDK: overview,
records, auth,
realtime, files,
batch-and-admin, and
ssr-and-cookies.
Shape
cb.collection(name)— typed CRUD:list/fullList/first/one/create/update/delete/subscribe, object-options only. Thefilter/rawtagged templates build safefilter=expressions without hand-escaping user input.list({ search })runs a full-text query over the collection'ssearchablefields, ANDed ontofilter(seefull-text-search).cb.auth— the whole authentication surface for one auth collection (cb.auth.as("_superusers")for another):signUp,signIn.password/.otp/.code/.social/.magicLink/.totp,signOut(now server-revoking, not just a client-side store wipe),refresh,sessions.*(list/revoke),admin.impersonate/.ban/.unban/.stopImpersonating, MFA via a401+mfaIdon the first factor, email verification, password reset, email change,magicLink.request(...),totp.setup/.confirm/.disable/.regenerateBackupCodes, andaccounts.list()/.unlink(provider)for a record's linked OAuth2 providers.cb.mails.send(...)/.preview(...)—POST /api/mails/send//preview: send by_emailTemplateskey ({{var}}data) or, as a superuser/API key, rawsubject/html/text. A template with asendRulecan be sent by any caller that rule allows, restricted to{to, template, data, locale}.cb.rpc<T>(name, params?)— call a saved_rpcdefinition (POST /api/rpc/{name}); named parameters bind as real driver parameters, gated by that definition's ownrule.cb.realtime/cb.collection(x).subscribe(...)— one shared SSE connection overfetch(noEventSource, no polyfill needed, works in Node/SSR too).cb.channel(name)— realtime channels not tied to any record:.subscribe(handler),.publish(event, data),.presence.track(state)/.list()/.onChange(kind, member). Gated by a_channelsrow'ssubscribeRule/publishRule(no matching row disables it by default); a member is auto-removed when its connection drops or after ~45s with no heartbeat.cb.notifications— in-app/email/push in one call:.send(...)(superuser/API key),.list/.fullList/.subscribe(the ordinary records API against_notifications),.unreadCount(),.markRead(id),.markAllRead().cb.files— file URLs (thumb, independentw/h/fit/format/qimage transforms,download, protected-file tokens) andcb.files.upload(file, { collection, field })— a presigned direct upload (straight to S3 or a same-origin local route, not through a multipart body) that returns a single-use token to pass as the field's value in thecreate/updatethat follows.cb.batch()runs several writes in one request/transaction.cb.admin.*— superuser-only management: collections, schema, settings, logs, backups, crons, storage, API keys, push, raw SQL.cb.vector,cb.llm,cb.mcp,cb.queue— the Cratebase-only value-add surface, built in.cb.presencealso still works (a client-side, collection-backed presence pattern predatingcb.channel(name).presenceabove) — prefer the channel-based one for anything new.
Pass a Schema generated by @cratebase/schema-codegen
to createClient<Schema>(url) for cb.collection("posts") to type its records off your actual
collection schema instead of a bare RecordModel.
To define collections in TypeScript instead of hand-written JSON, use
@cratebase/schema (defineSchema
writes the schema.json that cratebase dev applies).
Versioning
This package versions independently from the cratebase server binary — it's the first-party
client, not a build artifact of the Rust workspace. Publishing is triggered by pushing a
client-v<version> tag (see .github/workflows/publish-client.yml), kept separate from the
server's own v* tags so the release trains don't block on each other.
Development
bun install
bun run typecheck
bun run build # emit dist/