Getting started
Clone, install, run — five minutes from zero to your first collection.
Five minutes from clone to first item.
Prerequisites
Section titled “Prerequisites”- Bun ≥ 1.1 (
curl -fsSL https://bun.sh/install | bash) — the dev toolchain (workspaces, scripts,bun run dev) runs on Bun. - Optional: Postgres 14+ for production. Dev defaults to Bun’s built-in SQLite.
Bun is only required for local development. The same source runs on Bun, Node, Deno, Cloudflare Workers, Vercel, Netlify, AWS Lambda, Google Cloud Functions, and Azure Functions — see Deployment for the Node and Deno self-host steps.
Install + run
Section titled “Install + run”git clone https://github.com/backlex/backlex && cd backlexbun installcp apps/web/.dev.vars.example apps/web/.dev.vars
# Apply migrations to the local D1 that `bun run dev` serves frombun run db:migrate:d1
# Start Vite + Cloudflare miniflare in one process on :5173# (admin SPA + Worker bundled — no separate API port, no proxy)bun run devMigrate D1, not SQLite.
bun run devruns the Worker on Cloudflare’s miniflare, so it reads the local D1 database — not thebun:sqlitefile under.data/. Runningdb:migrate:sqliteinstead leaves every route answering500withno such table: tenantsin the server log. Usedb:migrate:sqliteonly for the Bun-native API (bun run dev:bun), anddb:migrate:pgwhen you pointDATABASE_URLat Postgres.
Open http://localhost:5173/sign-up and create the first user — they
auto-receive the admin role. Subsequent sign-ups get authenticated.
Your first collection
Section titled “Your first collection”In the admin UI, go to Collections → New and define:
slug: postsfields: - title (text, required) - body (longtext) - published (boolean) - views (integer)ownerScoped: trueClick Create. The API runs CREATE TABLE c_posts (...) against the
live database — no redeploy.
Your first items
Section titled “Your first items”Click on posts in the list, then + New item. Type-aware inputs
render based on field type (textarea for longtext, checkbox for boolean,
number input for views). Save.
The owner-scoped flag auto-seeds permissions for the authenticated
role: each user only reads/writes their own items. Admin sees all.
# RESTcurl http://localhost:5173/api/items/posts?limit=10 \ --cookie "$(cat /tmp/cookie.txt)"
# REST with filter (DSL — same as permissions)curl "http://localhost:5173/api/items/posts?filter=$(echo '{"published":{"_eq":true},"views":{"_gt":10}}' | jq -sRr @uri)&sort=-views"
# GraphQLcurl -X POST http://localhost:5173/api/graphql \ -H "content-type: application/json" \ -d '{"query":"{ posts(sort:\"-views\", limit:5) { id title views } }"}'Every route, in one place
Section titled “Every route, in one place”GET /api/openapi.json (admin auth) is the generated OpenAPI document for the
whole instance — every route, its body schema and its responses, with your
workspace’s own /api/items/{slug} paths filled in from your collections. Read
it before guessing a path: the admin surface is not uniformly prefixed
(/api/admin/kpis and /api/webhooks are both correct), and the spec is the
authority on which is which.
curl -s http://localhost:5173/api/openapi.json -H "Authorization: Bearer pak_…" \ | jq -r '.paths | keys[]' | grep bookingGenerate types for your client
Section titled “Generate types for your client”bun run backlex gen-types http://localhost:5173 --out src/types.tsThe CLI fetches /api/collections and emits one TypeScript interface per
collection plus a Collections registry. Use with backlex:
import { createClient } from "backlex";import type { Posts } from "./types";
const wks = createClient({ url: "http://localhost:5173" });const r = await wks.from<Posts>("posts").list({ filter: { published: { _eq: true } }, sort: "-views", limit: 10,});Deploy
Section titled “Deploy”One-click deploy clones the repo into your own Git account and ships it —
vercel.ts (Build Output API) and netlify.toml are already in the repo,
so no extra config is needed:
After the clone you still set the runtime env vars — Backlex needs a
Postgres URL (DATABASE_DRIVER=neon-http), S3-compatible storage, and
AUTH_SECRET. Full per-platform steps + every variable:
Deployment — also covers Bun, Node, Deno, Cloudflare
Workers, AWS Lambda, Google Cloud Functions, and Azure Functions.
Deno Deploy is also supported
(managed, experimental). There’s no one-click button — it ships via the
deno deploy CLI or a dashboard Git link rather than a clone URL — but the
same source runs on it (verified live), with neon-http + Upstash forced
automatically.
Already deployed? See Staying up to date to pull in later releases — migrations apply automatically on redeploy.
What next
Section titled “What next”- Migrating an external database in — copy your Postgres/MySQL/Mongo/… into Backlex, PKs preserved
- Permissions DSL — granular role + condition rules
- Auth planes — admin pool vs workspace end-user pool
- Third-party auth — accept Clerk / Auth0 / Firebase / Cognito / WorkOS tokens as they are
- Organizations — B2B teams inside a workspace, with
$org.idscoping - Sandbox functions — JavaScript code that runs in a sandbox
- AI agents — reason→act agents that call your tools, with per-thread memory
- MCP server — expose the workspace to Claude Desktop / Cursor / IDE agents
- Deployment — push to Bun, Workers, Vercel, Netlify, AWS Lambda, Google Cloud, or Azure
- Testing — three-layer pyramid (bun test / build-targets / runtime-smoke)