PostgreSQLOpen-source backend · MIT · Any Postgres

A backend for your Postgres.And an admin panel you don't have to build.

REST, a typed SDK, realtime, auth and storage for your app; spreadsheets, media, relations and roles for your team. Our own CRM is twenty-three collections and not one hand-written screen.

zsh · ~/work

$ pnpm dlx @rebasepro/cli init

✔ Access rules compiled into Postgres policies.

✔ API, realtime and panel running.

From the makers of FireCMS, the open-source CMS in 10,000+ projects.

DearDoc LogoMedicalMotion LogoProton HealthWithUSocial Income

01·How it works

You write this file.
You don’t write the rest.

Schema, REST API, typed SDK, edit forms and every panel view come out of it, and move when it moves. There is no second data model to keep in sync and no CRUD screen to go and maintain when a field changes name.

App Code — products.ts
import type { PostgresCollectionConfig }
  from "@rebasepro/types";

export const products: PostgresCollectionConfig = {
  name: "Products",
  slug: "products",
  table: "products",
  properties: {
    name: {
      name: "Name",
      type: "string",
      validation: { required: true },
    },
    category: {
      name: "Category",
      type: "string",
      enum: {
        electronics: "Electronics",
        fashion: "Fashion",
        home: "Home & Garden",
      },
    },
    price:     { name: "Price", type: "number" },
    in_stock:  { name: "In Stock", type: "boolean" },
    image_url: { name: "Image", type: "string", url: true },
  },
};

→ generates DB schema · REST API · Typed SDK · entity forms · admin views

02·What you get

Working APIs against your database, from minute one.

A typed SDK for your collections, REST over every table and realtime on a WebSocket, running against your database from minute one.

app.ts — typed from your collectionslive · try it
1
2
3
import { createRebaseClient } from '@rebasepro/client';
 
const data = await client.data.
TypeScriptUTF-8Ln 3, Col 1
REST, over every tablelive · send a request
Endpoints
GET/api/data/users
POST/api/data/users
GET/api/data/posts
PUT/api/data/posts/:id
DEL/api/data/posts/:id
Ready
Response
Send a request...
Realtime — LISTEN/NOTIFYlive
your app — web
name
status
upd
Alice
pending
2m ago
Bob
active
5m ago
Carol
inactive
1h ago
Dave
active
12m ago
ws
live
admin panel
name
status
upd
Alice
pending
2m ago
Bob
active
5m ago
Carol
inactive
1h ago
Dave
active
12m ago
Both clients subscribed to users…ws://localhost:3000/realtime

Plus auth and roles, S3-compatible storage, scheduled jobs, serverless functions and backups. None of it is a separate service to sign up for and wire together.

Explore the backend

And the admin panel your team opens every morning.

Spreadsheet editing, media, relations, roles and workflows — an admin panel you can hand a non-developer on their first day. It is a client of your API like any other, so whatever it can see, your policies said so.

What your app talks to

Rebase Backend

The server your app calls: REST, a typed SDK, realtime, auth and storage over your own Postgres.

@rebasepro/server

Where your team works

Rebase CMS

Spreadsheet editing, media, relations, roles and workflows — with your own React components dropped in wherever the default field isn't enough.

@rebasepro/cms

The developer half of the panel

Rebase Studio

SQL editor, schema visualizer, RLS policy editor, logs and API explorer. Studio is the developer half of the same panel your team already uses.

@rebasepro/app

Explore Rebase CMS

03·Security-first

Written in TypeScript. Enforced by Postgres.

Your access rules compile into real Postgres policies — granular per collection, per field, per role. The database holds them on every path into it: your routes, your nightly job, the backfill script someone ran once, the agent holding a key. Not middleware someone has to remember to call.

Where the rule lives todaycollections/orders.ts · one rule, in Postgres, on every path
routes/orders.tsif (order.ownerId !== req.user.id) return 403;✓ checks
jobs/nightly-report.tsdb.select().from(orders) // every row✗ no check
scripts/backfill.tsdb.update(orders).set(…) // run once, kept forever✗ no check
agents/tools.tsconnect(URL, SERVICE_ROLE_KEY)✗ bypasses RLS
the hosted dashboardselect * from orders -- as the owner✗ no policy
securityRules: [
  { operation: "select", using: "owner_id = rebase.uid()" },
  { operation: "update", using: "owner_id = rebase.uid()" },
]
-- compiled into Postgres; enforced on every statement, for every caller
CREATE POLICY orders_select ON orders FOR SELECT USING (owner_id = rebase.uid());
-- a table with no policy is not served at all
routes/orders.tsrebase_user→ policy applies
jobs/nightly-report.tsrebase_user→ policy applies
scripts/backfill.tsrebase_user→ policy applies
agents/tools.tsscoped key→ policy applies
the panelrebase_user→ policy applies

Don't take that on faith.

rls-check reads your database's own catalogue and reports what is actually exposed — tables served with row-level security switched off, policies that evaluate to true for everyone, views that read straight past the RLS on their base tables. Fifteen checks. Any Postgres: Supabase, Neon, RDS, your own server. It is read-only, it needs no account, and it does not care whether you use Rebase.

See all 15 checks
npx @rebasepro/rls-check

SELECTs against the system catalogues and nothing else. No telemetry, no upload, and it never reads your data.

04·Built for the agent era

The backend an agent can't screw up.

An AI agent can scaffold a backend in an hour. It can't tell you whether that backend is safe. Agents are extremely good at producing plausible backends — and famously bad at producing secure ones. Rebase makes the safe outcome the only outcome, by construction.

Explore AI and agent features
agent · what it can reach

A surface an agent can hold

No controllers, no serializers, no migrations to hand-write, and nothing for a model to invent between the schema and the route. The whole contract fits in one context window, and the compiler checks whatever it writes back.

config/collections/orders.ts
export const orders: PostgresCollectionConfig = {
table: "orders",
properties: { total, status, customer },
securityRules: [{ operation: "select", … }],
};
→ REST · typed SDK · RLS policies · admin views
no controllers to reviewfits in one context windowcompiler-checked

05·Built for real products

Seven products. All of them in production.

A certified medical device, a retail loyalty programme, a two-sided marketplace, public data, an outbound sales agent, a design tool and a CRM — some of them ours, some of them our customers'.

Point it at your database.

MIT-licensed, end to end. Your data stays in your Postgres: no vendor dependency, no per-seat pricing, and leaving is a redeploy.

Run it locally

One command against the Postgres you already have. No account, no container to pull, nothing to sign up for.

pnpm dlx @rebasepro/cli init
Quickstart

Self-host it

Docker, Fly, Railway, Hetzner or bare metal. Your data stays in your infrastructure and never reaches us.

docker compose up -d
Deployment guides

Rebase CloudPrivate beta

Managed hosting on our infrastructure. It runs real tenants today and opens in batches.

Request access