# Build with a coding agent

Install the Rindle skill into your assistant, prompt it for the integration you want, and check the result against the rules that keep an app correct.

Rindle's documentation is written to be read by coding agents, and this repository
publishes the same canon as an installable skill. This page is for the person doing
the setup: install the skill, prompt for the integration you want, then check the
result.

Two neighbouring pages cover different jobs.
[Rindle for coding agents](https://rindle.sh/docs/for-agents) is addressed to the assistant itself —
paste it when your assistant has no skill installed and only reads what you give it.
[Agents on live data](https://rindle.sh/docs/agents) is about an agent *inside* your application that
reacts to query changes.

## Install the skill

```sh
npx skills add rindle-sh/rindle --skill building-rindle-apps
```

The [`skills` CLI](https://github.com/vercel-labs/skills) clones the repository,
finds the skill, and installs it into the current project. It writes the files to
`.agents/skills/building-rindle-apps` — the shared location most assistants read —
and links the agent-specific directories that expect their own path, so one install
serves Claude Code, Codex, Cursor, Cline, and the other supported assistants. A
`skills-lock.json` file records what was installed and from where.

| Variant | Effect |
| --- | --- |
| `npx skills add rindle-sh/rindle --list` | List the repository's skills without installing |
| `npx skills add rindle-sh/rindle -g` | Install for your user account instead of one project |
| `npx skills add rindle-sh/rindle -a codex` | Install for one named assistant |
| `npx skills add rindle-sh/rindle -y` | Skip the confirmation prompt, for scripted setup |

The skill is named `building-rindle-apps`. Its description tells the assistant when
to load it: a prompt that names Rindle, `rindled`, or an `@rindle/*` package, or a
new project that needs local-first data, live queries, or client-server sync. It
carries eleven reference files generated from these documentation pages, so the
assistant reads Rindle's current API from disk rather than from training data.

Install it into the project you are building, not into the Rindle repository. Work
on Rindle itself is covered by that repository's `AGENTS.md` and `CLAUDE.md`.

## The Claude Code plugin

Claude Code can install a plugin instead. It contains the same skill plus three
things the skill alone cannot provide:

```
/plugin marketplace add rindle-sh/rindle
/plugin install rindle@rindle
```

| Component | What it does |
| --- | --- |
| `building-rindle-apps` skill | The same canon as the `skills` install |
| `quickstart` skill and `/rindle:quickstart` | Scaffolds a new app, boots it, and verifies the write loop before editing anything |
| `rindle-reviewer` agent | Audits changed Rindle code against the correctness rules rather than style |
| Write-time hook | Rejects removed APIs and non-deterministic mutator bodies before the edit reaches disk |

The hook inspects a file only when that file references `@rindle/`. Projects that do
not use Rindle are unaffected.

## Assistants without skill support

Every page on this site is served as Markdown, so an assistant with web access needs
no scraping and no plugin.

| URL | What it contains |
| --- | --- |
| [`/llms.txt`](https://rindle.sh/llms.txt) | An index of every page with its description |
| [`/llms-app.txt`](https://rindle.sh/llms-app.txt) | The synced-app documentation in one fetch |
| [`/llms-engine.txt`](https://rindle.sh/llms-engine.txt) | The engine, SQL, and runtime documentation in one fetch |
| [`/llms-full.txt`](https://rindle.sh/llms-full.txt) | The whole site, for ingestion |
| `/docs/<slug>.md` | Any single page, for example [/docs/mutators.md](https://rindle.sh/docs/mutators.md) |

Fetch the index and the pages for your task before a full bundle. A bundle is a
convenience for a long read, not the cheapest way to answer one question.

The [app scaffold](https://rindle.sh/docs/create-rindle) writes an `AGENTS.md` into the generated
project, so an assistant that opens that repository starts with the correctness
rules and links back to these pages even with no skill installed.

## Prompt for the outcome, not the package

An assistant that has the skill still needs to know which integration you want.
Rindle covers an in-process engine, a SQL database, a warm server read model, and a
full synced application. Those have different runtimes, different deployment costs,
and different failure modes. Name the outcome and the constraint; the skill selects
the packages.

| You want | Prompt with something like |
| --- | --- |
| A new synced app | "Build a new Rindle app for issue tracking. Use the scaffold, then add an issues table and a live list." |
| Sync in an existing app | "Add Rindle sync to this Next.js app. Keep the existing routing and auth; use the manual setup, not the scaffold." |
| Local live queries only | "Use Rindle in the browser for live queries over in-memory rows. No server, no sync, no daemon." |
| SQL from a server | "Query the Rindle database from this API route with @rindle/sql-client. Request/response only." |
| Live views in Rust | "Embed SQLite with live queries in this Rust service using rindle-replica." |
| A warm server result | "Keep this leaderboard query warm on the server and read it per request." |

State the constraints you care about — the framework, whether a daemon is acceptable,
whether writes must be optimistic. The skill is instructed to keep an existing stack
and to explain the tradeoffs before adopting Rindle, but it cannot infer a limit you
did not mention.

A worked prompt for the most common case:

```
Build a Rindle app for tracking issues.

Scaffold it with create-rindle and get it running before making changes.
Then: an `issues` table with title, status, and assignee; a live list
filtered by status; and an optimistic mutator to change an issue's status.
Keep the scaffold's TanStack Start setup and its dev identity.
```

## What a good first run looks like

For a new synced app, the assistant should scaffold with `create-rindle`, run the
development command, and confirm the app works *before* it starts editing. The
scaffold is a working rooms-and-messages app with every seam already wired; it is a
baseline to change, not a set of snippets to copy into a half-wired project.

The checks worth seeing in the transcript:

1. Node.js 22.18 or later. No Rust toolchain is needed — `@rindle/cli` ships prebuilt binaries.
2. The development command starts the data tier, applies `migrations/*.sql`, regenerates the typed schema, seeds, and serves the app.
3. A write appears immediately in the browser and survives a reload. That is the optimistic path and the synced path, proven separately.
4. Only then, the changes you asked for.

An assistant that starts writing mutators before the baseline runs is debugging two
things at once. Ask it to boot the scaffold first.

## Check the agent's work

Rindle's correctness contract is **view-after-write == fresh-query**: the maintained
result equals a fresh query over the same data. The rules that preserve it are
exactly the ones an assistant gets wrong unaided, because they are Rindle-specific
rather than general TypeScript practice. Read the diff for these:

| Check | Why it matters |
| --- | --- |
| `schema.gen.ts` is untouched | It is regenerated from the database. DDL belongs in a new [migration](https://rindle.sh/docs/schema). |
| Mutators are one shared body | An [isomorphic mutator](https://rindle.sh/docs/mutators) uses `shared(args, generator)` and runs on both tiers. A hand-written server twin that duplicates the client body will drift. |
| No `Date.now`, `Math.random`, or `crypto.randomUUID` inside a mutator body | Mutators re-run on every rebase. Generate ids and timestamps at the callsite and pass them as arguments. |
| Synced reads go through a named query | A synced client subscribes with `defineQuery`. A bare `store.query` builder only sees rows that are already local. |
| Authorization is on the server | The browser sends a query name and arguments. It does not receive the database token. See [authorization](https://rindle.sh/docs/authorization). |
| Views and queries are released | Removing a listener does not necessarily destroy the query. See the [client guide](https://rindle.sh/docs/client). |

Then test the behaviour rather than the code. The [testing guide](https://rindle.sh/docs/testing)
covers local prediction, server confirmation, [rejected writes](https://rindle.sh/docs/rejected-writes),
and a second client's updates. [Devtools](https://rindle.sh/docs/devtools) shows what a client actually
subscribed to, which is usually faster than reading the query module. When data is
missing or a write snaps back, [troubleshooting](https://rindle.sh/docs/troubleshooting) lists the
known causes.

Claude Code users can run the plugin's `rindle-reviewer` agent over the changed files
for the same audit.

## What the skill does not do

The skill is documentation and rules. It does not provision anything, hold
credentials, or grant database access. It does not choose your authentication
provider or replace the deployment decisions in [deploying and scaling](https://rindle.sh/docs/deploy).

It also does not make a preview surface production-ready. The
[Postgres source](https://rindle.sh/docs/postgres-source) is a preview with open release gates; an
assistant will follow its documentation, including the limits, but the limits still
apply.

Where an assistant and the installed package disagree, the package's types and the
[API map](https://rindle.sh/docs/api) win. Say so in the prompt when you are on a version older than
the documentation.

## Next steps

- [Getting started](https://rindle.sh/docs/getting-started) — the same choice of first project, for a human reader.
- [Is Rindle for you?](https://rindle.sh/docs/compare) — the tradeoffs, before an assistant commits you to them.
- [Rindle for coding agents](https://rindle.sh/docs/for-agents) — the routing page to hand an assistant directly.
- [Guides](https://rindle.sh/docs/guides) — task guides for whatever the assistant builds next.

---

[View this page on Rindle](https://rindle.sh/docs/build-with-an-agent)
