Get an Instant REST API From Your Database

Get an Instant REST API From Your Database
For most apps, the backend is a thin layer: take an HTTP request, check who’s asking, run a query, return JSON. Writing and hosting a service to do that — per table, per project — is a lot of ceremony for CRUD.
The alternative is a database that generates the API for you. You define the tables; every one gets a REST endpoint and a realtime channel, gated by rules you write next to the schema. This is the model behind Supabase (Postgres + PostgREST) and Firebase, and it’s what PocketBase does in a single process.
Define a collection, get an API
Create a collection — posts, with a title, a body, and an author
relation — in the admin UI or a migration. Immediately you have:
GET /api/collections/posts/records list, with filter + sort + paginate
GET /api/collections/posts/records/:id one record, related data expanded
POST /api/collections/posts/records create
PATCH /api/collections/posts/records/:id update
DELETE /api/collections/posts/records/:id delete
Plus a realtime subscription over Server-Sent Events:
import PocketBase from "pocketbase";
const pb = new PocketBase("https://<id>.<compute>.pocketbasecloud.com");
const posts = await pb.collection("posts").getList(1, 20, {
filter: 'status = "published"',
sort: '-created',
expand: 'author',
});
pb.collection("posts").subscribe("*", (e) => {
console.log(e.action, e.record);
});
No route handlers, no ORM, no serializers.
Authorization is a rule, not middleware
Each operation on a collection takes a filter expression. The list rule below means “anyone can read published posts, and authors can see their own drafts”; the update rule means “authors can change only their own”:
list rule: status = "published" || author = @request.auth.id
update rule: author = @request.auth.id
The rules live with the schema and apply to every request through the API — there is no separate policy layer to keep in sync.
Auth is built in
Email/password, OAuth2 (Google, GitHub, Apple, …), and one-time passwords are
part of the same API. @request.auth.id in a rule is the logged-in user; the
JS SDK attaches the token for you after authWithPassword.
When you do need custom code
Anything the generated API can’t express — a Stripe webhook, a nightly job, an enrichment step before a write — runs as a JavaScript hook inside the same process, or as a separate backend if it needs its own runtime.
Hosting it
On PocketBase Cloud this is one deploy: your schema and rules ship with the instance, and you get a hosted database with its API behind automatic HTTPS for a flat monthly price — no per-read billing, and the data is a standard PocketBase directory you can export any time.
cd db && pbc deploy --name my-app-db