Skip to content
Onboarding contents

OnboardingFirst steps

Scaffold with create-rindle

Generate and run a TanStack Start app with SQL migrations, a synced browser client, an API server, and SSR.

View as Markdown

Build an app with live messages, optimistic writes, and a shared database. create-rindle generates the browser client, API server, and local data tier in a TanStack Start project.

This guide starts the app on your computer. You will see a message sync between two browser windows, then change the generated project.

Use this starter when you want a new synced TypeScript app with routing and server rendering included. To add sync to another framework, use the manual quickstart. For local queries without a server, start with the browser engine. For remote reads or normalized sync without prediction, compare the browser clients. For an embedded Rust database, use rindle-replica.

Before you start

You need Node.js 22.18 or later and npm or pnpm. The starter uses TypeScript and React. It includes the local Rindle binaries and requires no cloud account.

1. Create the project

With pnpm, run:

pnpm create rindle my-app
cd my-app
pnpm dev

With npm, run:

npm create rindle@latest my-app
cd my-app
npm run dev

The generator installs dependencies with your package manager. The development command starts the app at localhost:3000.

2. See live updates

  1. Open localhost:3000 in two browser windows.
  2. Create a room in the first window.
  3. Open the room in both windows.
  4. Post a message in the first window.

The message appears immediately in the first window and syncs to the second. The room’s message count updates with each message.

To see a rejected write, create a room named spam. The room appears briefly, then disappears when the API server rejects it. A toast explains the rejection.

The starter includes a development identity so you can write immediately. Before production, replace it with your own authentication provider.

3. Understand the development command

The generated dev script runs one lifecycle command:

rindle dev --migrate --gen shared/schema.gen.ts -- vite dev --port 3000

rindle dev reads rindle.ncl and starts the local write master, follower, and fleet edge. The master accepts database writes. The follower serves live queries, and the edge routes requests to them. The command applies migrations and generates shared/schema.gen.ts. Then it starts TanStack Start with RINDLE_URL and RINDLE_DATABASE_TOKEN.

The database token stays on the server. The browser calls the app’s /api/rindle/* routes. An authorized subscription response, called a lease, gives it the endpoint for live updates.

What it generates

The starter generates the same three tiers as the manual quickstart:

Tier In the template What it does
Browser src/rindle-client.ts, src/rindle-tanstack.ts, src/components/*.queries.ts, src/routes/* Displays live query results and predicts writes immediately
API authority server/app-api.ts, server/rindle-http.ts, src/routes/api.rindle.*.tsx Checks access, resolves named queries, and runs authoritative mutators
Data tier rindle.ncl, migrations/*.sql Stores data, applies migrations, and sends live query changes

The schema is SQL-first. Edit or add migrations/*.sql. The dev loop applies the migration to the write master and regenerates shared/schema.gen.ts from the follower’s introspected schema. A file can be pure DDL (including reviewed destructive drops) or pure DML for seeds and bounded backfills. Keep the two kinds in separate ordered files. Keep relationships, normalization, and mutators in shared/app-def.ts.

Why TanStack Start

The starter uses TanStack Start because it gives the template one home for the browser, SSR, and server routes:

  • src/routes/api.rindle.query.tsx, api.rindle.read.tsx, and api.rindle.mutate.tsx are the browser-facing API routes.
  • SSR reads call the same app authority in-process, so first paint and client subscriptions use the same query registry.
  • @rindle/tanstack lets each file route declare its query once, then owns server preloading, client navigation readiness, cancellation, and the seed-to-live provider handoff.
  • TanStack Router’s file routes keep app screens and Rindle query modules close without forcing the Rindle APIs themselves to depend on TanStack.

This template chooses the optimistic client and a replicated data tier. Other Rindle integrations do not require that combination. TanStack Start is the template’s application framework; the query engine and client APIs also work outside it.

Where to look first

File Why it matters
migrations/0001_init.sql The source-of-truth SQL schema
shared/schema.gen.ts Generated @rindle/client schema; do not hand-edit
shared/app-def.ts Schema re-export, relationships, normalization, and predicted mutators
src/components/*.queries.ts Named root queries and fragments, co-located with UI
src/rindle-client.ts The one browser client setup call
src/rindle-tanstack.ts The shared route-loader/provider integration
src/ssr.ts Server-only first-paint preload helper
src/devtools.tsx Dev-only Rindle devtools panel mount
server/app-api.ts Authoritative query registry, SQL mutators, policy
rindle.ncl The topology rindle dev (local) and rindle deploy (cloud) both read — followers = 1, the colocated pair; loopback in dev
AGENTS.md App instructions for coding agents, including generated files, mutators, and named queries

Customize it

Treat the generated app as a working baseline:

  • Change tables in migrations/*.sql, then let pnpm dev regenerate the typed schema.
  • Add relationships and mutators in shared/app-def.ts.
  • Add named root queries or fragments beside the components that read them.
  • Replace the demo auth seam in shared/auth.ts and the policy in server/app-api.ts.
  • If you point the app at Rindle Cloud or a self-hosted fleet, keep RINDLE_DATABASE_TOKEN server-only.

The same rindle.ncl drives the cloud:

  1. Run rindle login.
  2. Run pnpm rindle:deploy. It provisions (or re-attaches) the Sync plan — a managed master + follower on Rindle’s packed OVH fleet — and records the binding in .rindle/cloud.json. Commit that file.
  3. Run pnpm rindle:migrate:cloud to push migrations/*.sql through the Cloud proxy.

Local dev reads the same authored topology through rindle dev. See deploy.

For the underlying commands, see @rindle/cli. For the manual version of the same app shape, keep the quickstart open beside the generated project.

Next steps