Le schéma comme du code.
Tout le reste suit.
Vous écrivez des collections en TypeScript. Rebase garde la base de données, l'API, les types et — si vous l'avez activé — le panneau en accord avec ce seul fichier. Lancez pnpm dlx @rebasepro/cli init, puis rebase dev, et c'est déjà en route.
La boucle
Quatre commandes, et ensuite vous écrivez juste du 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 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 devRun it, with no database to install
Backend and panel together with hot reload. No DATABASE_URL? A managed Postgres starts with them — nothing to install, no Docker, no compose file to maintain.
Le projet
Trois dossiers, une définition
config/collections/ est le seul endroit où votre modèle de données est décrit. Le backend le lit pour servir les API et générer le schéma Drizzle ; le panneau lit les mêmes fichiers pour se rendre.
Supprimez frontend/ et vous avez un backend headless. Rien sous backend/ n'importe React, et le système de types l'impose — une clé admin dans un projet qui ne l'a jamais activé est une erreur de compilation.
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, …Votre code
Généré ne veut pas dire fermé
Chaque surface générée a une couture que vous pouvez ouvrir : des callbacks autour des écritures, vos propres routes sur le serveur, votre propre React dans le panneau, et du SQL brut quand l'abstraction gêne.
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] },
);
},
},
};La logique métier s'exécute sur le serveur, sur tous les chemins d'écriture — y compris les écritures faites depuis le panneau d'administration.
// 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/checkoutDéposez un fichier dans functions/ et il est monté, authentifié et soumis à la RLS sans aucune étape d'enregistrement.
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:postgresResources
Déclarez ce dont vous avez besoin. Dans le code, une fois.
Bases de données, buckets et topics sont des constructeurs, pas du YAML. Chacun nomme son propre moteur — Postgres, MongoDB, Firestore, SQLite ; disque local, S3, GCS, Azure — et un moteur dont nous n'avons jamais entendu parler s'écrit custom: et est accepté, pour qu'il échoue au point d'appel plutôt que de ressembler à une faute de frappe.
rebase resources génère le graphe qu'un hébergeur lit avant de construire quoi que ce soit, et --check fait échouer la CI quand le graphe committé et votre code divergent. Il n'y a pas de second endroit pour déclarer un bucket, et c'est tout l'intérêt : deux domiciles pour un même fait, c'est l'un des deux qui perd en silence.
// 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 });Publier dans une transaction qui échoue n'a jamais été publier. Chaque abonné réessaie selon son propre calendrier, et celui qui abandonne est une ligne que vous pouvez consulter.
Architecture
Où chaque pièce tourne réellement
Votre navigateur, votre serveur, votre base de données. Rien ne passe par nous — il n'y a pas de nous dans le chemin de la requête.
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
Ship it
Il se déploie comme l'application Node qu'il est
Le backend se compile en bundle et tourne derrière ce que vous utilisez déjà. Le panneau d'administration est une SPA statique — servez-le depuis le même processus ou depuis un CDN.
Un processus est la valeur par défaut et le reste. Quand vous le dépassez, le même bundle démarre en API, en étage de fonctions et en worker — REBASE_ROLE par processus, et c'en découle quelles routes sont montées, quels minuteurs se déclenchent et qui possède le schéma. Exactement un processus migre ; les autres se vérifient contre la base et le signalent en cas de désaccord.
En auto-hébergé, chaque déploiement est le vôtre : votre base, votre machine, vos logs. Rebase Cloud, notre hébergement managé, fait tourner le même bundle pour vous — il est aujourd'hui en bêta privée et s'ouvre par vagues.
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.
Vos agents aussi
Apprenez Rebase à votre agent de code
rebase skills install écrit des instructions empaquetées dans Claude Code, Cursor, Windsurf ou Gemini, pour qu'un agent travaillant dans votre dépôt sache déjà comment collections, politiques et panneau s'articulent. Le serveur MCP lui donne des outils — introspection de schéma, migrations, requêtes, stockage, cron — sous une clé à portée limitée à laquelle la sécurité au niveau des lignes s'applique toujours.
Lancez la boucle.
Une commande échafaude le projet, génère le SDK depuis votre schéma et lance le panneau à côté.