TypeScript · Postgres · your editor

Schema as code.
Everything else follows.

You write collections in TypeScript. Rebase keeps the database, the API, the types and — if you opted in — the admin panel in agreement with that one file. Clone the repo, run rebase dev, and it is already up: no Postgres to install, no Docker, no compose file to maintain.

zsh
>pnpm dlx @rebasepro/cli init

The loop

Four commands, and then you are just writing TypeScript

01

rebase init

Scaffold, 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 push

Move 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-sdk

Regenerate the types

Writes a typed client from your collections — or from a running backend with --from <url>, in a repo that has no schema of its own.

04

rebase dev

Run it, with no database to install

Backend and panel together with hot reload. No DATABASE_URL? A managed Postgres starts with them — no install, no Docker, no compose file.

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 — an admin key in a project that never opted in is a compile error.

after rebase init
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, …

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.

config/collections/orders.tscallbacks
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.tscustom routes
// 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/checkout

Drop a file in functions/ and it is mounted, authenticated and RLS-scoped with no registration step.

rebase-workspace / schema_definition.ts
Workspace Live
TypeScript Model definition
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 } }
  }
};
AST Mutator will append new fields to this file automatically when edited in UI.
Visual Studio Schema EditorUNAPPLIED AST CODE CHANGES

Rebase lets non-technical editors build database schemas visually. Any change updates the database instantly and generates type-safe AST code modifications.

Posts Scheme
id
uuid
title
text
Active Engine: drizzle-kit push:postgres

Resources

Declare what you need. In code, once.

Databases, buckets and topics are constructors, not YAML. Each one names its own engine — Postgres, MongoDB, Firestore, SQLite; local disk, S3, GCS, Azure — and an engine we have never heard of is spelled custom: and accepted, so it fails at the call site instead of looking like a typo.

rebase resources generates the graph a host reads before it builds anything, and --check fails CI when the committed graph and your code disagree. There is no second place to declare a bucket, which is the point: two homes for one fact means one of them is silently losing.

config/resources.tsdeclared once
// config/resources.ts
import { database, bucket, topic } from "@rebasepro/types";

export const analytics = database("analytics", { engine: "mongodb" });
export const media     = bucket("media", { engine: "s3", transport: "direct" });
export const signups   = topic<{ userId: string }>("signups");

signups.subscription("send-welcome", async (event) => {
  // durable, at-least-once, retried on its own schedule
});

await signups.publish({ userId });

Publishing inside a transaction that rolls back was never published. Each subscriber retries on its own schedule, and one that gives up is a row you can look at.

Architecture

Where every piece actually runs

Your browser, your server, your database. Nothing routes through us — there is no us in the request path.

Database Layer
PostgreSQL
PostgreSQL
Drizzle ORM · Pooling · Read replicas
MongoDB
MongoDB
v7 document driver
BranchingMigrationsIntrospection
BaaS Coreserver
Auth & Security
Email/password · JWT · Refresh tokens · Rate limiting
12 OAuth ProvidersMFAAPI Keys
Row-Level SecurityRolesLifecycle Hooks
Realtime Engine
WebSocket server · PostgreSQL LISTEN/NOTIFY · Auto-reconnect
BroadcastPresenceCollection SubsEntity Subs
Storage & Files
S3-compatible: AWS, MinIO, R2, Hetzner, DO, B2, GCS
Local FSTUS UploadsImage TransformsSigned URLsMedia Manager
Compute & Services
Cron Scheduler
5-field parser, DB logs
Custom Functions
Hono routes, auth + DB
EmailWebhooksHistorySearch
API Layerauto-generated from schema
REST
CRUD, filters, sort, pagination, eager-loading
WebSocket
Subs, broadcast, presence
OpenAPI
3.0 spec + Swagger UI
Typed SDK@rebasepro/clientBrowser · Node · Serverless · Edge
Generator
database.types.ts
Enums · Relations · Nested maps
Client Modules
rebase.data.*rebase.auth.*rebase.realtime.*rebase.storage.*rebase.functions.*rebase.cron.*rebase.email.*rebase.admin.*
CLI
@rebasepro/cli
$ init
$ dev
$ schema generate
$ schema introspect
$ db push
$ db migrate
$ db branch create
$ generate-sdk
$ doctor
$ build
$ start
$ deploy
$ skills install

Orchestrates schema, migrations, SDK codegen, dev server, and builds.

Frontend Layer
Rebase Platform
Rebase Studiodev tools
SQL Console
Monaco + EXPLAIN
JS Runner
Live SDK sandbox
RLS Editor
Visual policies
Schema Viz
Interactive ERD
API Explorer
Test endpoints
Storage Mgr
File browser
Cron Jobs
Task scheduler
Logs
Real-time viewer
Branches
DB branching
Rebase AdminCMS
Collections
Table · Card · List · Kanban
Entity Forms
20+ field bindings
Rich Text
Notion-like editor
Import/Export
CSV · JSON · Excel
Custom Views
Your React pages
History
Timeline + revert
Side Panels
Slide-over editing
Home Builder
DnD dashboard
i18n
7 languages
Your Application
built with the SDK + UI Kit
React
Next.js
Remix
Astro
Vue
Svelte
Angular
Node.js
Mobile
UI Kit@rebasepro/ui
55+
components
4
views
VirtualTableKanban BoardResizable PanelsForm ControlsDialogs & SheetsData DisplayMarkdownLayout

Schema-as-Code · Git-Backed · Hot Reload · Self-Hostable · TypeScript End-to-End · 21 Packages

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.

One process is the default and stays the default. When you outgrow it, the same bundle boots as an API, a functions tier and a worker — REBASE_ROLE per process, and which routes mount, which timers fire and who owns the schema all follow from it. Exactly one process migrates; the rest check themselves against the database and say so if they disagree.

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.

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.

~rebase skills install
The agent story in full

Ready to build?

One command scaffolds the whole thing, and it runs on a managed database straight away. Name a DATABASE_URL — your own Postgres, a colleague's staging box, a Neon branch — and Rebase steps aside and uses exactly that.

~pnpm dlx @rebasepro/cli init