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-as-a-service on Cloudflare Workers. The entire backend is defined in a single teenybase.ts config file — no backend code.
Install CLI
npm install -g teenybaseThis gives you the teeny command globally.
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
teeny 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, teeny create launches arrow-key prompts that hang when stdin is not a TTY.
| 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 byteeny generate.gitignore— ignoresnode_modules,.local-persist,.dev.vars,.prod.vars,migrations
Start the local dev server:
teeny generate --local
teeny deploy --local
teeny dev --localAPI 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
teeny initteeny init 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 teeny init does not modify an existing package.json, you must install the dependencies yourself (the npm install lines above).
After init, start the local dev server:
teeny generate --local
teeny deploy --local
teeny dev --localKey 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, strong values). Not auto-created — copy from .dev.vars. |
migrations/ | Auto-generated SQL. Don't edit manually. |
CLI commands
teeny create <name> [-t <tpl>] [-y] # Scaffold new project (runs npm install)
teeny init [-t <tpl>] [-y] # Add teenybase to existing project
teeny generate --local # Generate migrations from config changes
teeny deploy --local # Apply migrations to local database
teeny dev --local # Start local dev server (port 8787)
teeny deploy --remote # Deploy to Teenybase Cloud
teeny register # Create Teenybase Cloud account (free)
teeny login # Log in
teeny status # Show deployed URL and status
teeny secrets --remote --upload # Upload .prod.vars to production
teeny list # List deployed workers
teeny delete [name] # Delete a deployed worker
teeny --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, run teeny status and use the exact URL it prints, then 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", "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" }
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
teeny generate --local(generates migrations) - Run
teeny deploy --local(applies migrations) - Run
teeny dev --local(starts server) - Test with curl or frontend
- When ready:
teeny deploy --remote