# TypeScript SDK

> Generate a fully-typed client for your collections, auth, and realtime.

_Updated: 2026-06-10_

Railbase generates a TypeScript client from your schema, so your frontend gets
typed CRUD, auth, and realtime with autocomplete — no hand-written API layer and
no drift between client and server.

## Generate the client

```bash
railbase generate sdk --out ./web/src/client
```

This emits a self-contained client — an `index.ts` entry, `types.ts`, `zod.ts`,
a `collections/<name>.ts` per collection, plus `auth.ts`, `realtime.ts`,
schema-independent modules (`account.ts`, `tenants.ts`, `notifications.ts`,
`i18n.ts`, `stripe.ts`, `contact.ts`, `errors.ts`) and a `_meta.json` used for
drift detection. It's a **full regenerate** each time; commit the output and
never hand-edit it.

> [!TIP]
> Add `--check` in CI to fail the build when the committed client drifts from the
> schema (`railbase generate sdk --check` exits non-zero on mismatch). Or let
> `railbase dev --watch-schema` regenerate it as you code.

## Use it

```ts
import { createRailbaseClient } from "./client";

export const rb = createRailbaseClient({
  baseURL: "",                  // same-origin in prod; "http://localhost:8095" in dev
  storage: window.localStorage, // persist the bearer token across reloads
  storageKey: "rb_token",
});

// Typed CRUD — `posts` is generated from your collection
const { items } = await rb.posts.list({ filter: "status='published'", sort: "-created" });
const post = await rb.posts.create({ title: "Hello", status: "draft" });

// Auth — a `<name>Auth` helper per auth collection. The built-in
// `_users` is always generated:
const { token, record } = await rb._usersAuth.signinWithPassword({
  identity: "you@example.com",
  password: "…",
});
await rb._usersAuth.signup({ email, password, passwordConfirm });
const me = await rb.me();

// Realtime
rb.realtime.subscribe({ topics: ["posts/*"] }, (evt) => console.log(evt));
```

The client stores the token in the `storage` you pass and attaches it to every
request; call `rb.setToken()` / `rb.setTenant()` to change identity at runtime.

## Other generators

```bash
railbase generate openapi --out openapi.json   # OpenAPI 3.1 spec
railbase generate schema-json --out schema.json # machine-readable schema (for tooling)
```

> [!NOTE]
> The SDK generator targets TypeScript. Other languages can consume the OpenAPI
> spec above.
