Agent Quickstart
Copy-paste this page into your AI agent's chat to give it full context on teenybase.
Introduction
You are working with teenybase, a backend framework that deploys to the user's own Cloudflare account (Workers + D1 + R2). The entire backend is defined in a single teenybase.ts config file — no backend code.
Run the CLI
Run every command as npx teenybase <command>. After npm install -g teenybase, teeny <command> works too. Never use npx teeny: it downloads an unrelated npm package named teeny.
Early (v0.1): APIs may change before 1.0.
Setup
There are two paths depending on whether this is a new project or an existing one. Infer which from conversation context (e.g. the user already has a package.json, or says "add a backend to my app" → Option B). If unclear, ask: "Are we starting a new project or adding teenybase to an existing one?"
Option A: New project
npx teenybase create my-app -t with-auth -y
cd my-appImportant: Always pass -t and -y when running non-interactively (scripts, CI, coding agents). Without them, a command that needs to ask a question fails with exit code 1 when stdin is not a TTY, and the error names the flag to pass.
| Flag | What it does |
|---|---|
-t, --template <template> | Set the project template. Values: with-auth (users table + auth + rules) or blank (empty project). |
-y, --yes | Skip all confirmation prompts and use defaults. |
If neither flag is given, the CLI prompts interactively for template and deploy target.
This creates the directory, scaffolds all files, and runs npm install. You're ready to go.
Files created:
package.json— deps:teenybase,hono ^4, devDeps:wrangler ^4,typescript ^5,@cloudflare/workers-types ^4teenybase.ts— backend config (tables, auth, rules)src/index.ts— worker entry point (imports teenybase, wires up Database + extensions)wrangler.jsonc— Cloudflare Workers config with D1 bindingPRIMARY_DB.dev.vars— local secrets:JWT_SECRET,JWT_SECRET_USERS,ADMIN_JWT_SECRET,ADMIN_SERVICE_TOKEN,POCKET_UI_VIEWER_PASSWORD,POCKET_UI_EDITOR_PASSWORDworker-configuration.d.ts— TypeScript type forCloudflareBindingstsconfig.json— includes path alias"virtual:teenybase": ["./teenybase"]migrations/— empty, auto-populated bygenerate/deploy.gitignore— ignoresnode_modules,.local-persist,.dev.vars,.prod.vars,migrations
Apply the migrations and start the local dev server:
npx teenybase deploy --local --yes
npx teenybase devAPI is at http://localhost:8787/api/v1.
Option B: Add to existing project
npm install teenybase hono
npm install -D wrangler @cloudflare/workers-types typescript
npx teenybase init -yinit detects existing files and only creates what's missing. It will not overwrite your package.json — it only creates one if none exists. If you already have a tsconfig.json, it patches in the "virtual:teenybase": ["./teenybase"] path alias without replacing it.
Important: Since init does not modify an existing package.json, you must install the dependencies yourself (the npm install lines above).
After init, apply the migrations and start the local dev server:
npx teenybase deploy --local --yes
npx teenybase devKey files
| File | Purpose |
|---|---|
teenybase.ts | Backend config — tables, fields, auth, rules, actions. In most apps, this is the main file you edit. |
src/index.ts | Worker entry point. Usually unchanged unless you need custom routes or R2 storage. |
wrangler.jsonc | Cloudflare Workers config, D1/R2 bindings |
.dev.vars | Local secrets (6 keys: JWT_SECRET, JWT_SECRET_USERS, ADMIN_JWT_SECRET, ADMIN_SERVICE_TOKEN, POCKET_UI_VIEWER_PASSWORD, POCKET_UI_EDITOR_PASSWORD) |
.prod.vars | Production secrets (same keys). Generated with random values on the first remote deploy. Gitignored. |
migrations/ | Auto-generated SQL. Don't edit manually. |
CLI commands
npx teenybase create <name> [-t <tpl>] [-y] # Scaffold new project (runs npm install)
npx teenybase init [-t <tpl>] [-y] # Add teenybase to existing project
npx teenybase generate --local # Generate migrations from config changes
npx teenybase deploy --local --yes # Generate + apply migrations to the local database
npx teenybase dev # Start local dev server (port 8787)
npx wrangler login # One-time: authenticate with Cloudflare
npx teenybase deploy --remote --yes # Deploy to the user's Cloudflare account
npx teenybase secrets --remote --upload # Upload .prod.vars to production
npx teenybase logs # Stream logs from the deployed worker
npx teenybase --help # List commands and optionsConfig format
import { DatabaseSettings } from 'teenybase'
import { baseFields, authFields, createdTrigger, updatedTrigger } from 'teenybase/scaffolds/fields'
export default {
appUrl: 'http://localhost:8787',
jwtSecret: '$JWT_SECRET', // Resolved from .dev.vars / .prod.vars
appName: 'My App',
tables: [
{
name: 'users',
autoSetUid: true,
fields: [...baseFields, ...authFields],
triggers: [createdTrigger, updatedTrigger],
extensions: [
{ name: 'auth', jwtSecret: '$JWT_SECRET_USERS', jwtTokenDuration: 3600, maxTokenRefresh: 5 },
{ name: 'rules', createRule: 'true', viewRule: 'auth.uid == id', listRule: 'auth.uid == id', updateRule: 'auth.uid == id', deleteRule: 'auth.uid == id' },
],
},
{
name: 'posts',
autoSetUid: true,
fields: [
...baseFields,
{ name: 'title', type: 'text', sqlType: 'text' },
{ name: 'body', type: 'text', sqlType: 'text' },
{ name: 'author', type: 'text', sqlType: 'text' },
{ name: 'published', type: 'bool', sqlType: 'boolean', default: '0' },
],
triggers: [createdTrigger, updatedTrigger],
extensions: [
{ name: 'rules', listRule: 'published == true', viewRule: 'published == true', createRule: 'auth.uid == author', updateRule: 'auth.uid == author', deleteRule: 'auth.uid == author' },
],
},
],
} satisfies DatabaseSettingsIf you keep the default scaffold from teeny create, it also includes authCookie: { name: 'teeny_auth' } and passwordConfirmSuffix: 'Confirm' on the users auth extension. authCookie enables cookie-based sessions for OAuth redirect callbacks and any SSR layer you add; sign-up and password-reset requests must include passwordConfirm.
In the posts example above, set author to the signed-in user's record.id on insert so the ownership rules line up with auth.uid == author.
API endpoints
Base URL: http://localhost:8787/api/v1 (local). For deployed apps, use the worker URL printed by npx teenybase deploy --remote (also saved in infra.jsonc) and append /api/v1.
CRUD:
POST /table/{table}/insert { "values": {...}, "returning": "*" }
GET|POST /table/{table}/select ?where=...&order=...&limit=...
GET|POST /table/{table}/list Same as select but returns { items, total }
GET /table/{table}/view/{id}
POST /table/{table}/update { "where": "id == '...'", "setValues": {...} }
POST /table/{table}/edit/{id} { "field": "value" }
POST /table/{table}/delete { "where": "id == '...'" }Auth:
POST /table/{table}/auth/sign-up { "username", "email", "password", "passwordConfirm", "name" }
POST /table/{table}/auth/login-password { "identity", "password" }
POST /table/{table}/auth/refresh-token { "refresh_token" }
POST /table/{table}/auth/request-password-reset { "email" }
POST /table/{table}/auth/confirm-password-reset { "token", "password", "passwordConfirm" }
POST /table/{table}/auth/request-verification Authorization: Bearer <token>
POST /table/{table}/auth/confirm-verification { "token" }
POST /table/{table}/auth/logout Authorization: Bearer <token>
POST /auth/logout Clears auth cookie onlyAuth header: Authorization: Bearer <token>
Other:
GET /health
GET /doc/ui # Swagger UI
GET /doc # OpenAPI 3.1.0 JSONWorkflow
- Edit
teenybase.ts - Run
npx teenybase deploy --local --yes(generates and applies migrations) - Keep
npx teenybase devrunning (it reloads after each local deploy) - Test with curl or the frontend
- When ready:
npx wrangler login(once), thennpx teenybase deploy --remote --yes