A Baseflare backend is a standard Cloudflare Worker.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/nickruigrok/baseflare/llms.txt
Use this file to discover all available pages before exploring further.
createWorker(manifest) from baseflare/server produces a Cloudflare ExportedHandler — the Worker’s default export. The deploy model has no management infrastructure sitting between you and Cloudflare: the CLI talks directly to the Cloudflare API to provision resources, bundle your code, apply schema changes to D1, and upload the Worker script. Once deployed, requests hit your Worker directly with zero intermediary hops.
createWorker(manifest)
createWorker accepts a BaseflareManifest and returns the fetch handler object that Cloudflare expects as the Worker’s default export. The CLI generates the Worker entry point automatically on deploy — you do not write this code by hand. The generated entry point passes the manifest fields that the CLI has already assembled, including discovered function entries indexed by canonical name, the schema, rules, config, and the optional HTTP router.
BaseflareManifest) accepts the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
schema | Schema | ✅ | The schema produced by defineSchema(). Used for write-time validation and schema application on deploy. |
rules | Rules | — | Permissions produced by defineRules(). Deny-by-default: if omitted, all access is denied. |
queryEntries | BaseflareFunctionEntry[] | — | Registered public query definitions, indexed by canonical name. |
mutationEntries | BaseflareFunctionEntry[] | — | Registered public mutation definitions. |
actionEntries | BaseflareFunctionEntry[] | — | Registered public action definitions. |
internalQueryEntries | BaseflareFunctionEntry[] | — | Internal queries, not exposed via RPC. |
internalMutationEntries | BaseflareFunctionEntry[] | — | Internal mutations, not exposed via RPC. |
internalActionEntries | BaseflareFunctionEntry[] | — | Internal actions, not exposed via RPC. |
http | HttpRouter | — | Optional HttpRouter instance from httpRouter() for custom HTTP routes. |
config | BaseflareConfig | — | Optional config from defineConfig(). |
queries:listTodos). Duplicate canonical names within the same manifest cause buildBaseflareManifest to throw at startup.
How Requests Are Routed
When a request arrives,createWorker evaluates routes in a fixed priority order and returns the first match. If no route matches, a NOT_FOUND error is returned.
POST /api/query/:name
Runs the named public query. The route name is URL-decoded from the path segment after
/api/query/. Non-POST requests to a query path return a VALIDATION_ERROR with the message "Query RPC requests must use POST".POST /api/mutation/:name
Runs the named public mutation. Non-POST requests to a mutation path return a
VALIDATION_ERROR with the message "Mutation RPC requests must use POST".POST /api/action/:name
Runs the named public action. Non-POST requests to an action path return a
VALIDATION_ERROR with the message "Action RPC requests must use POST".Custom HTTP routes
Routes registered on the
HttpRouter via http.route() or http.routeWithPrefix(). The router matches by HTTP method and exact path (or prefix for routeWithPrefix).internalQuery, internalMutation, internalAction) are not reachable over RPC. They can only be called server-side via ctx.runQuery(), ctx.runMutation(), or ctx.runAction().
RPC Request Format
All RPC calls usePOST with a JSON body shaped exactly as { "args": ... }. The body must not be empty, must be valid JSON, and must contain only the args key. Any deviation returns a VALIDATION_ERROR.
VALIDATION_ERROR.
RPC Response Format
All RPC responses are JSON. A successful call wraps the return value in aresult envelope. An error wraps a structured payload in an error envelope.
400 for VALIDATION_ERROR, 403 for PERMISSION_DENIED, 404 for NOT_FOUND, 409 for CONFLICT, 501 for NOT_IMPLEMENTED, and 500 for all other errors. INTERNAL_ERROR responses always use the generic message "Internal error" — details are logged internally and never sent to the client.
Schema Application
createWorker does not run DDL during requests. Schema application — CREATE TABLE, CREATE INDEX, and related D1 statements — is a deploy-time step run by the CLI against your D1 database before traffic is routed to the new Worker version.
The schema diffing rules are:
| Change | Behaviour |
|---|---|
| Add field | No-op — JSON document model, validation at write time |
| Remove or rename field | No-op — old documents return the field on read until rewritten |
| Change field type | No-op — validation catches mismatches at write time |
| Add table | Safe — CREATE TABLE applied automatically |
| Remove table from schema | Orphan — table kept read-only, dashboard shows warning with row count |
| Add or drop index | Safe — CREATE INDEX / DROP INDEX applied automatically |
baseflare deploy never destroys data. Orphaned tables can be deleted manually via the dashboard after you have confirmed the data is no longer needed.
Worker Bindings
The Worker expects a D1 database bound asAPP_DB in the Cloudflare runtime environment. In CLI-managed deployments this binding is configured automatically. For manual deployments using wrangler, add the binding to your wrangler.toml:
APP_DB is fixed — it is the identifier the runtime reads from env.APP_DB on every request. Future phases add additional bindings for R2 (FILES), Durable Objects (REALTIME_CONNECTIONS, REALTIME_SUBSCRIPTIONS, SCHEDULER), and Vectorize (VECTORS), all managed automatically by the CLI.
The full CLI deploy workflow — auto-provisioning Cloudflare resources, applying schema changes, bundling the Worker, and uploading via the CF API — is in active development as part of Phase 4. Currently, manual deployment via
wrangler with the D1 binding configured above is supported.Error Codes
The Baseflare runtime uses a fixed set of error codes inerror.code responses. These codes are sourced from the ErrorCode constant in baseflare/values:
| Code | HTTP Status | When it occurs |
|---|---|---|
VALIDATION_ERROR | 400 | Malformed request body, invalid arguments, failed schema or return validation |
UNAUTHORIZED | 401 | Missing or invalid auth token |
PERMISSION_DENIED | 403 | Auth token present but rules deny the operation |
NOT_FOUND | 404 | Named function or route does not exist |
CONFLICT | 409 | Optimistic concurrency conflict after retry exhaustion |
MALFORMED_DOCUMENT | 500 | A stored document cannot be deserialized from D1 |
DATABASE_ERROR | 500 | D1 returned an error or unexpected result |
NOT_IMPLEMENTED | 501 | Feature not yet implemented in the current runtime |
INTERNAL_ERROR | 500 | Unexpected runtime error — details logged internally, message sanitized |
new BaseflareError(data) propagate to the client with their structured data payload intact. The code field is read from data.code if present, otherwise it defaults to INTERNAL_ERROR.