El esquema como código.
Todo lo demás va detrás.
Escribes colecciones en TypeScript. Rebase mantiene la base de datos, la API, los tipos y — si lo has activado — el panel de acuerdo con ese único archivo. Ejecuta pnpm dlx @rebasepro/cli init, luego rebase dev, y ya está en marcha.
El bucle
Cuatro comandos, y a partir de ahí solo escribes 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.
El proyecto
Tres carpetas, una definición
config/collections/ es el único sitio donde se describe tu modelo de datos. El backend lo lee para servir las APIs y generar el esquema de Drizzle; el panel lee los mismos archivos para renderizarse.
Borra frontend/ y tienes un backend headless. Nada bajo backend/ importa React, y el sistema de tipos lo obliga: una clave admin en un proyecto que nunca lo activó es un error de compilación.
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, …Tu código
Generado no significa cerrado
Cada superficie generada tiene una costura que puedes abrir: callbacks alrededor de las escrituras, tus propias rutas en el servidor, tu propio React en el panel y SQL en crudo cuando la abstracción estorba.
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 lógica de negocio se ejecuta en el servidor, en toda ruta de escritura — incluidas las escrituras hechas desde el panel de administración.
// 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/checkoutDeja un archivo en functions/ y queda montado, autenticado y sujeto a RLS sin ningún paso de registro.
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
Declara lo que necesitas. En código, una vez.
Las bases de datos, los buckets y los topics son constructores, no YAML. Cada uno nombra su propio motor — Postgres, MongoDB, Firestore, SQLite; disco local, S3, GCS, Azure — y un motor del que nunca hemos oído hablar se escribe custom: y se acepta, para que falle en el punto de llamada en vez de parecer una errata.
rebase resources genera el grafo que un host lee antes de construir nada, y --check hace fallar la CI cuando el grafo confirmado y tu código no coinciden. No hay un segundo sitio donde declarar un bucket, y ese es el punto: dos hogares para un mismo hecho significa que uno de ellos está perdiendo en silencio.
// 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 });Publicar dentro de una transacción que se revierte no fue publicar nada. Cada suscriptor reintenta según su propia planificación, y el que se rinde es una fila que puedes mirar.
Architecture
Dónde se ejecuta realmente cada pieza
Tu navegador, tu servidor, tu base de datos. Nada pasa por nosotros — no hay ningún nosotros en la ruta de la petición.
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
Se despliega como la aplicación Node que es
El backend se compila a un bundle y corre detrás de lo que ya uses. El panel de administración es una SPA estática — sírvelo desde el mismo proceso o desde una CDN.
Un proceso es el valor por defecto y sigue siéndolo. Cuando se te queda pequeño, el mismo bundle arranca como API, capa de funciones y worker — REBASE_ROLE por proceso, y de ahí se derivan qué rutas se montan, qué temporizadores disparan y quién es dueño del esquema. Exactamente un proceso migra; el resto se comprueban contra la base de datos y lo dicen si no coinciden.
Autoalojado, cada despliegue es tuyo: tu base de datos, tu máquina, tus logs. Rebase Cloud, nuestro hosting gestionado, ejecuta el mismo bundle por ti — hoy está en beta privada y se abre por tandas.
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.
Tus agentes, también
Enséñale Rebase a tu agente de código
rebase skills install escribe instrucciones empaquetadas en Claude Code, Cursor, Windsurf o Gemini, para que un agente que trabaje en tu repositorio ya sepa cómo encajan las colecciones, las políticas y el panel. El servidor MCP le da herramientas — introspección de esquema, migraciones, consultas, almacenamiento, cron — bajo una clave con alcance a la que la seguridad a nivel de fila sigue aplicándose.
Empieza el bucle.
Un comando genera el proyecto, produce el SDK desde tu esquema y levanta el panel al lado.