teenybase · a teeny tiny Supabase for your own Cloudflare account

One file in. A backend on your Cloudflare.

teenybase turns one TypeScript file into a REST API with auth, access rules, migrations, OpenAPI docs and an admin panel, deployed to your own Cloudflare account. Open source, Apache-2.0.

Open source, Apache-2.0Runs on your Cloudflare accountNothing to keep running

Start herepick one, copy, paste

$ npx teenybase create my-app --yes

Then cd my-app, npx teenybase deploy --local --yes and npx teenybase dev. Runs on your machine, no account.

Use teenybase (run `npx teenybase docs` first) to build the backend for a notes app in this folder: people sign up with email and password, write notes, and only see their own. Run it locally and show me it working.

Paste it into Claude Code, Codex or Cursor. No account needed to run it locally; step-by-step versions are below.

your CloudflareaccountWorkers + D1nothing to keeprunningmy appSign inadmin3 rowsusersposts1ada@x.io2lin@x.io3sam@x.ioauthrules → SQLteenybase10000_create_table_users.sqlREST API· 7 routes per table/api/v1/table/usersGET/selectGET/listPOST/insertPOST/updatePOST/deleteGET/view/:idPOST/edit/:id+ 13 auth routes on usersusersteenybase.tstables: [{ name: 'users', extensions: [ { name: 'auth' }, { name: 'rules', viewRule: 'auth.uid == id' },] }]migrationsmy appSign in

One file describes your tables. teenybase gives every table 7 REST routes (select, list, insert, update, delete, view, edit) and a table with auth 13 more, so a users table answers 20 endpoints; it writes one migration per table, serves the API docs and an admin panel, and deploys to your own Cloudflare account (Workers + D1) with wrangler login and npx teenybase deploy --remote --yes. No account yet: npx teenybase deploy --temporary runs for 60 minutes. Apache-2.0.
Loading the figure…
Figure

Quick start

01

Every way to start ends with the same project: a teenybase.ts file, a Worker and a D1 database.

$ npx teenybase create my-app --yes

Then cd my-app, npx teenybase deploy --local --yes and npx teenybase dev. Runs on your machine, no account.

A real run of the default template on localhost:8787: sign up, list with the token (one row), list without it (none: the list rule is auth.uid == id).
From zero to a running APIterminal
# 1. Local: no account, runs on your machine
$ npx teenybase create my-app --yes
✓ Project ready!
$ cd my-app
$ npx teenybase deploy --local --yes
+ Migrations applied
$ npx teenybase dev
  CRUD:    /api/v1/table/{table}/[select | list | view/:id | insert | update | edit/:id | delete]
  Auth:    /api/v1/table/{table}/auth/[sign-up | login-password | refresh-token | ...]
  Swagger: http://localhost:8787/api/v1/doc/ui
  Admin:   http://localhost:8787/api/v1/pocket/ (passwords in .dev.vars)

# 2. Your Cloudflare account
$ npx wrangler login
$ npx teenybase deploy --remote --yes
[creating the D1 database, uploading secrets, deploying the Worker, applying migrations…]

# 3. No Cloudflare account yet: a temporary one, claim it within 60 minutes
$ npx teenybase deploy --temporary --yes
[prints the live URL, a claim link and when it expires]

Copy a prompt for your AI

02

Paste one into Claude Code, Codex or Cursor in an empty folder. Each one runs as written: we ran all three, step by step, against the CLI before putting them here. The apps they made are in Real apps.

Set up the backend for a notes app with teenybase, in this folder.

1. Run `npx teenybase create notes-app --yes`, then `cd notes-app`.
2. Run `npx teenybase docs` and read config-reference.md (the rules section) and recipe-full-app.md in the folder it prints.
3. Edit teenybase.ts: keep the users table (email and password sign-up) and add a notes table with owner_id (a relation to users.id), title, content and is_public. Rules: anyone can list and view public notes; a signed-in user can create notes owned by themselves and list, view, update and delete only their own.
4. Run `npx teenybase deploy --local --yes`, then start `npx teenybase dev` in the background.
5. Check it with curl against http://localhost:8787/api/v1: sign up a user (include passwordConfirm), create one private and one public note with the token, then list notes with and without the token. Show me the results and the Swagger UI and admin panel URLs.

No account needed: npx teenybase deploy --temporary --yes puts the same backend on a temporary Cloudflare account for 60 minutes; claim it to keep it.

What you get

03

One file, teenybase.ts, describes your tables, auth and rules. From it you get:

Database + REST API

Seven routes per table (select, list, view, insert, update, edit, delete) on D1 (SQLite), with an OpenAPI 3.1 spec and Swagger UI. Migrations are generated by diffing the config.

Auth

Email and password, OAuth (Google, GitHub, Discord, LinkedIn), email verification and password reset, with JWTs and refresh tokens.

Access rules

Per table, in TypeScript strings like auth.uid == owner_id, compiled to parameterized SQL. A table with no rules is denied until you add them or mark it public: true.

Admin panel

At /api/v1/pocket/ in apps made from the templates: browse and edit rows. A fork of the PocketBase admin UI.

File uploads

File fields stored in Cloudflare R2. Only needed if your tables have files.

Made for agents

The whole backend is one typed file an agent can read and change, and the CLI ships its docs and skills: npx teenybase docs, npx teenybase skills.

Fig 2one file to a backend An excerpt of teenybase.ts (a users table with the auth and rules extensions) becomes, after deploy, a REST API, auth endpoints, rules compiled to SQL, generated migrations, an OpenAPI spec with Swagger UI and an admin panel, running on your own Cloudflare account (Workers + D1).
Fig 2. The with-auth template's users table and what it turns into.
The admin panel: the users table with three rows (lena, jonas, maya), their ids, created and updated times, emails and names.
Admin panel at /api/v1/pocket/, a fork of the PocketBase admin UI (MIT).
Swagger UI listing the users table's routes: select, list, update, insert, delete, view and edit, then auth routes like login-token, google-login and oauth.
Swagger UI at /api/v1/doc/ui, from the generated OpenAPI 3.1 spec.

How rules work

04

A rule is a small expression in your config. teenybase compiles it to SQL and appends it to the WHERE of every query on that table, so a row the rule doesn't allow is never read, changed or deleted. The signed-in user's id goes in as a bound parameter, never into the SQL text. Admin and service tokens skip rules.

Fig 3a rule and the SQL it becomes

teenybase.ts · users table (the with-auth template)

listRule: 'auth.uid == id'

Signed in as user u_7Hq2xK: the clause, then its bound parameter

({:fdxu9ko6l} IS ([users].[id]))
{"fdxu9ko6l": "u_7Hq2xK"}

Signed out

(NULL IS ([users].[id]))

teenybase.ts · notes table (prompt 1)

listRule: 'is_public == true | auth.uid == owner_id'

Signed in as user u_7Hq2xK: the clause, then its bound parameter

((([notes].[is_public]) IS 1) OR ({:fsah7kb48} IS ([notes].[owner_id])))
{"fsah7kb48": "u_7Hq2xK"}

Signed out

((([notes].[is_public]) IS 1) OR (NULL IS ([notes].[owner_id])))
Fig 3. Signed out, auth.uid is NULL and no row's id is NULL, so the list is empty: the last line of the quick-start run above. Signed out, only public notes match.

The SQL above is the output of teenybase's own compiler (src/sql/parse), the same call its rules extension makes for a list request; the parameter names are random per query. More in the rules reference.

Real apps

05

Everything here runs on the current CLI. The pictures are captures from real runs, not mock-ups.

Questions

06
What is teenybase?

Teenybase is an open-source (Apache-2.0) backend framework for Cloudflare Workers and D1: a teeny tiny Supabase for your own Cloudflare account. You define tables, auth, access rules and actions in one TypeScript file (teenybase.ts); teenybase turns it into a REST API with OpenAPI docs, generated SQL migrations, auth endpoints and an admin panel.

How do I try it?

Run npx teenybase create my-app --yes, then cd my-app, npx teenybase deploy --local --yes and npx teenybase dev. The API runs at http://localhost:8787/api/v1 with no account. To deploy to your own Cloudflare account, run npx wrangler login, then npx teenybase deploy --remote --yes. New: npx teenybase deploy --temporary --yes deploys to a temporary Cloudflare account without a login and prints a claim link; claim it within 60 minutes or it is deleted.

Where does my data live?

In a Cloudflare D1 database (SQLite) in your own Cloudflare account. npx teenybase backup exports the schema and data as standard SQL (remote export is blocked for databases with FTS5 tables, a Cloudflare limitation).

How much does teenybase cost?

Teenybase is free and open source. It runs on your Cloudflare account, so you pay Cloudflare directly for Workers, D1 and R2 usage; the Workers free plan is enough to start.

Is teenybase good for AI coding agents?

Your whole backend is one typed TypeScript file that an agent can read and change, and the CLI ships its docs and skills (npx teenybase docs, npx teenybase skills) so the agent can look up auth, OAuth, uploads and rules itself.

How does teenybase compare to Supabase?

Supabase is a Postgres platform (hosted or self-hosted); access control is written as SQL policies, and schema is usually managed in its dashboard or SQL migrations. Teenybase keeps schema, auth and rules in a TypeScript file in your repo and runs on your Cloudflare account. Supabase is the better fit for Postgres features, live subscriptions and a larger ecosystem.

How does teenybase compare to Firebase?

Firebase is a proprietary Google Cloud service with a document database. Teenybase is open source and relational (SQLite), and your data can be exported as SQL. Firebase is the better fit for live sync and mobile SDKs.

How does teenybase compare to PocketBase?

Both put schema, auth and rules in one place and have an admin UI (teenybase's is a fork of PocketBase's). PocketBase is a single Go binary you host yourself, manages schema in its admin UI and has live subscriptions. Teenybase is config-as-code in TypeScript and runs on Cloudflare Workers with no server to manage. PocketBase is more mature.

What are the limits?

Teenybase runs on Cloudflare Workers and D1 only today. A D1 database is capped at 10 GB (500 MB on the free plan) and has a single primary location. There are no live subscriptions: the API is REST only. Teenybase is early (v0.1), and APIs may change before 1.0.

teenybase · open source under Apache-2.0 · GitHub · npm · X · Docs · llms.txt Admin panel: a fork of the PocketBase admin UI (MIT) · figures drawn with anatomy (MIT) · Inter and Newsreader (OFL)