Schema as code.
Everything else follows.
You write collections in TypeScript and run four commands. Rebase keeps the database, the API, the types and — if you opted in — the admin panel in agreement with that one file. No generated code to babysit, no UI to re-draw.
01·The loop
Four commands, and then you are just writing TypeScript
01
rebase initScaffold, or adopt what exists
Creates the three packages and wires them together. Already have a database? rebase schema introspect writes collections from your tables instead.
02
rebase db pushMove the schema
Diffs your collections against the database and applies the change. db generate + db migrate when you want the SQL in version control.
03
rebase generate-sdkRegenerate the types
Writes database.types.ts. From here a renamed column is a compile error in your app, not a runtime surprise.
04
rebase devRun both halves
Backend and admin panel together with hot reload — the API on :3001, the panel on :5173.
02·The project
Three folders, and one of them is optional
config/collections/ is the only place your data model is described. The backend reads it to serve APIs and generate the Drizzle schema; the panel reads the same files to render itself.
Delete frontend/ and you have a headless backend. Nothing under backend/ imports React, and the type system enforces it — anadmin key in a project that never opted in is a compile error.
my-app/
├── config/collections/ # the source of truth
│ ├── index.ts
│ └── orders.ts # properties · relations · securityRules · admin
│
├── backend/ # Hono server
│ ├── src/index.ts # initializeRebaseBackend(…)
│ ├── src/schema.generated.ts # Drizzle, generated
│ └── functions/ # your own routes, auto-mounted
│
├── frontend/ # the admin panel — delete it and nothing breaks
│ └── src/App.tsx
│
└── .env # DATABASE_URL, JWT_SECRET, …03·Your code
Generated does not mean closed
Every generated surface has a seam you can open: callbacks around writes, your own routes on the server, your own React in the panel, and raw SQL when the abstraction is in the way.
export const orders = {
slug: "orders",
callbacks: {
onPreSave: async ({ values, context }) => {
values.total = recalculate(values.items);
return values;
},
onSaveSuccess: async ({ entity, context }) => {
await context.rebase.sql(
"INSERT INTO ledger (order_id) VALUES ($1)",
{ params: [entity.id] },
);
},
},
};Business logic runs on the server, on every write path — including writes made from the admin panel.
// backend/functions/checkout.ts
import { Hono } from "hono";
const app = new Hono();
app.post("/", async (c) => {
const { user, rebase } = c.get("rebase");
// same auth context, same RLS as every other request
return c.json({ ok: true });
});
export default app;
// → POST /api/functions/checkoutDrop a file in functions/ and it is mounted, authenticated and RLS-scoped with no registration step.
import type { PostgresCollectionConfig } from "@rebasepro/types"; export const postsCollection: PostgresCollectionConfig = { name: "Posts", slug: "posts", table: "posts", properties: { id: { name: "ID", type: "string", validation: { required: true } }, title: { name: "Title", type: "string" }, status: { name: "Status", type: "string", validation: { required: true } } } };
Rebase lets non-technical editors build database schemas visually. Any change updates the database instantly and generates type-safe AST code modifications.
drizzle-kit push:postgres04·Architecture
Where every piece actually runs
Your browser, your server, your database. Nothing routes through us — there is no us in the request path.
serverRow-Level SecurityRolesLifecycle Hooks@rebasepro/clientBrowser · Node · Serverless · Edgedatabase.types.tsrebase.data.*rebase.auth.*rebase.realtime.*rebase.storage.*rebase.functions.*rebase.cron.*rebase.email.*rebase.admin.*@rebasepro/cliOrchestrates schema, migrations, SDK codegen, dev server, and builds.
@rebasepro/uiSchema-as-Code · Git-Backed · Hot Reload · Self-Hostable · TypeScript End-to-End · 21 Packages
05·Ship it
It deploys like the Node app it is
The backend builds to a bundle and runs behind whatever you already use. The admin panel is a static SPA — serve it from the same process or from a CDN.
Rebase Cloud, our managed hosting, has not launched yet. Until it does, every deployment is yours: your database, your machine, your logs.
Self-hosting guide- DockerA Dockerfile ships with every scaffolded backend.
- RailwayPush the repo, set DATABASE_URL, done.
- Fly.ioOne process, one region or several.
- Hetzner · bare metalIt is a Node server. Run it the way you run Node.
- AWS · GCP · Azure · ScalewayA deployment guide per provider in the docs.
- Your existing Hono appMount the backend as a sub-app instead of deploying it separately.
06·Your agents, too
Teach your coding agent the framework
rebase skills install writes packaged instructions into Claude Code, Cursor, Windsurf or Gemini, so an agent working in your repo already knows how collections, policies and the panel fit together. The MCP server gives it tools — schema introspection, migrations, queries, storage, cron — under a scoped key that row-level security still applies to.
Ready to build?
One command scaffolds the whole thing. It runs against a local Postgres, or the one you already have.
