CloudflareBase is one of the more ambitious Cloudflare-native projects in this series.
It is not a single Docker app, and it is not only a dashboard. It is trying to be a Firebase-style backend platform where auth, database, realtime, storage, remote config, and hosting all run on Cloudflare primitives.
That makes it a good follow-up to the Cloudflare Workers, D1, KV, and R2 serverless stack post. CloudflareBase is what happens when that idea grows into a reusable backend platform.
What is CloudflareBase?
CloudflareBase describes itself as:
The open-source Firebase alternative on Cloudflare.
The core idea is architectural isolation. Each project gets its own Durable Objects, so tenant separation is not just a WHERE project_id = ... condition in one shared database.
It currently covers:
- authentication with Better Auth;
- JSON document collections;
- typed SQL-style tables;
- realtime subscriptions;
- remote config and feature flags;
- R2-backed file storage;
- static/app hosting through Workers for Platforms;
- CLI deployment workflows;
- dashboard management UI;
- generated OpenAPI documents per project.
The project is Apache-2.0 licensed ❤️.
The Most Important Self-Hosting Detail
CloudflareBase is self-hostable, but not in the usual homelab Docker sense.
Self-hosting here means:
deploy the CloudflareBase control plane and agents into your own Cloudflare account
It does not ship a docker-compose.yml, Postgres service, Redis service, or local single-node server stack.
That is consistent with the product: it is built around Workers, Durable Objects, D1, R2, service bindings, Analytics Engine, Workers AI, and Workers for Platforms.
If you want a container you can run on a Raspberry Pi or VPS without Cloudflare, CloudflareBase is the wrong shape. If you want a Firebase-like backend that lives in your Cloudflare account, it is exactly the kind of project to inspect.
Architecture Overview
CloudflareBase is a dashboard Worker plus multiple backend agents.
| Component | What It Does | Main Cloudflare Primitives |
|---|---|---|
| Dashboard / console | SvelteKit UI, project registry, API proxy, setup and operator flows | Workers, D1, service bindings, Rate Limiting |
| Auth agent | Better Auth per project, users, sessions, roles, JWTs | Durable Objects with SQLite, optional Email, optional Analytics Engine |
| Database agent | JSON collections, typed tables, live queries, remote config, views | Durable Objects with SQLite, WebSockets, optional Analytics Engine |
| Storage agent | Buckets, access modes, signed URLs, object index | R2 plus Durable Objects |
| Hosting agent | Static sites and Workers under app subdomains | Workers for Platforms, Durable Objects |
| CLI | Init, add agents, deploy, service keys, schema generation | npm package plus Wrangler |
This is a very different shape from something like FeedLog or Seeder.
| Project | Main Shape | Local/Homelab Path | Cloudflare Path |
|---|---|---|---|
| FeedLog | Feedback, roadmap, changelog | Docker app + Postgres/pgvector | Workers-compatible, but still needs Postgres |
| Seeder | Project/client workspace | Single Docker container + SQLite | Workers + D1 + R2 |
| CloudflareBase | Backend platform/Firebase alternative | Local dev only, no Docker deployment | Native multi-Worker platform on your Cloudflare account |
CloudflareBase is the most platform-like of the three. It is less “install this app” and more “deploy a backend-as-a-service into your Cloudflare account.”
What Each Primitive Provides
The README mentions many Cloudflare services, so it is worth separating required pieces from optional enhancements.
| Cloudflare Primitive | Why CloudflareBase Uses It | Required? |
|---|---|---|
| Workers | Runs the dashboard and every agent | Yes |
| Durable Objects with SQLite | Per-project/per-collection/per-table state and isolation | Yes |
| D1 | Control-plane project registry for the dashboard | Yes for the console |
| Service bindings | Private dashboard-to-agent calls | Yes in the multi-worker install |
| R2 | File bytes for storage buckets | Needed for full storage |
| Rate Limiting binding | API abuse control | Configured in the dashboard Worker |
| Analytics Engine | Auth/database/hosting charts | Optional |
| Workers AI | Copilot/chat surfaces | Optional |
send_email |
Verification and auth email | Optional |
| Workers for Platforms | User app hosting and functions | Optional paid feature |
| Sentry | Error reporting | Optional |
That “optional” wording matters.
The README states that storage needs R2, hosting needs Workers for Platforms, auth-event charts need Analytics Engine, and Google/GitHub sign-in, email, and Sentry are opt-in. Without those, the relevant feature degrades or returns setup guidance instead of taking the entire platform down.
Database Model: Powerful, But Not PostgreSQL
CloudflareBase’s database is clever, but you need to understand the constraints before comparing it with Supabase.
JSON documents are Firestore-like. You create collections, write documents, query them, and subscribe to live changes over WebSockets.
Typed tables are schema-first and can be queried through a Drizzle-style interface.
The architectural tradeoff is this:
one collection or table = one Durable Object with its own SQLite database
That gives strong isolation and scale-by-shard behavior, but it also means CloudflareBase is not a normal relational database cluster.
The README calls out important boundaries:
- SQL is single-table by design;
- filters, aggregates, subqueries, and CTEs are supported in that model;
- cross-table joins happen through read-only views;
- views replicate 2-5 member tables into one SQLite database;
- views are eventually consistent, around a few seconds, and meant for reporting reads;
- realtime subscriptions send snapshots and deltas over WebSockets.
For Firebase-like app data, this is a good fit.
For general OLTP with broad joins, arbitrary transactions, and a single relational schema, PostgreSQL is still the more natural model.
Hosted vs Self-Hosted
There are two ways to think about CloudflareBase.
The hosted path is the normal SaaS path: create an account, create a project, point your app at its project API, and use the console.
The self-hosted path deploys the stack into your Cloudflare account:
git clone https://github.com/cloudflarebase/cloudflarebase.git
cd cloudflarebase
npm install
npx wrangler login
npm run deploy:all
npx wrangler secret put CONSOLE_SETUP_TOKEN
CONSOLE_SETUP_TOKEN is the first thing I would not skip.
The setup token proves that you control the deployment before the first console owner is created. Without a claim gate, a fresh public Workers URL could be claimed by the first person who visits /login.
Local Development
The README documents a local demo mode:
npm install
npm run dev
The dev script starts several processes:
| Process | Port |
|---|---|
| Auth agent | 8788 |
| Database agent | 8789 |
| Hosting agent | 8790 |
| Storage agent | 8791 |
| Dashboard | 5173 |
In local mode, the dashboard runs with demo behavior enabled. That is useful for development, but it is explicitly not how you should operate a private production deployment.
Field Note: My Local Trial
I did not complete the local run on this machine because the available runtime is too old.
The repository pins:
Node 22.18.0
This environment has:
Node 18.19.1
npm 9.2.0
Running install failed immediately with:
npm ERR! code EBADENGINE
npm ERR! engine Unsupported engine
npm ERR! notsup Required: {"node":"^22.18.0 || >=24.11.0"}
So for readers: use Node 22.18.0 or a newer supported Node 24 release before trying npm install.
Comparison: CloudflareBase vs Rolling Your Own Workers Stack
You can absolutely build a Cloudflare app directly with Workers, D1, KV, R2, Durable Objects, Queues, and Cron.
CloudflareBase sits one level higher.
| Approach | Good For | Tradeoff |
|---|---|---|
| Raw Workers + D1/KV/R2 | One app with explicit architecture | You build auth, realtime, dashboard, SDKs, admin flows |
| CloudflareBase | Many app backends with reusable primitives | You adopt its platform model and Durable Object boundaries |
| Firebase | Mature managed backend | Proprietary, Google-owned platform |
| Supabase | PostgreSQL-first backend platform | Less Cloudflare-native, more database/server stack oriented |
My mental model:
Firebase = managed product backend on Google
Supabase = open Postgres backend platform
CloudflareBase = open backend platform built around Workers and Durable Objects
FAQ
Can I run CloudflareBase with Docker Compose?
No, not as a normal deployment.
CloudflareBase is a Cloudflare-native platform. It is designed to run on Workers, Durable Objects, D1, R2, service bindings, and optional Workers for Platforms.
You can run local development with Node and Wrangler, but that is different from a portable Docker Compose stack.
Is CloudflareBase fully serverless?
Yes, in the Cloudflare sense.
There are no VMs, no Postgres server, no Redis container, and no OS patching. The main persistent state lives in D1 for control-plane data and Durable Object SQLite for project/application data, with R2 for file bytes.
The tradeoff is strong Cloudflare coupling. This is not an app you can later move to a generic VPS without rewriting major runtime assumptions.
What do the README feature claims mean in practical terms?
The tagline is accurate, but it needs the Cloudflare context around it.
When CloudflareBase says it is “the open-source Firebase alternative on Cloudflare”, it means the Firebase-like pieces are implemented with Cloudflare primitives instead of a single shared database service.
| README claim | Practical meaning |
|---|---|
| “Every project gets its own Durable Objects” | Each project, collection, table, bucket, or agent can map to its own Durable Object scope. That gives physical runtime/storage separation inside Cloudflare’s platform rather than putting every tenant into one shared SQL schema. |
| “Isolation by architecture, not by a WHERE clause” | Tenant isolation does not depend only on remembering WHERE tenant_id = ... in every query. The system routes project data into separate Durable Object instances, each with its own embedded SQLite state. |
| Auth | Better Auth is wrapped per project inside the auth agent. It handles email/password, social sign-in, roles, permissions, sessions, bearer tokens, and project-signed JWTs used by the other agents. |
| Database | The database agent offers schema-less JSON collections and typed table-like storage. Live queries work through WebSockets. The tradeoff is that SQL is scoped around table/collection Durable Objects, not a general PostgreSQL cluster. |
| Remote Config | Feature flags and runtime values live with the database agent. Clients can fetch defaults plus targeted overrides by country, role, version, or rollout percentage without shipping a new app version. |
| Storage | File bytes live in R2, while Durable Objects keep bucket metadata, object indexes, access modes, and signed URL behavior. Public/auth/owner modes decide who can read or write. |
| Hosting | Hosting uses Workers for Platforms, not a normal static web server. It can serve static sites and Worker code under app subdomains such as <app>.cfbase.dev, but that feature needs Workers for Platforms and the matching dispatch namespace/domain setup. |
The main takeaway: CloudflareBase is not “Firebase API cloned on a VPS.” It is a Firebase-style product model rebuilt around Workers, Durable Objects, D1, R2, service bindings, and optional Workers for Platforms.
How is Better Auth used here, and does it replace Firebase Auth, Logto, or PocketBase Auth?
CloudflareBase uses Better Auth inside its auth agent.
The important detail is that Better Auth is not being used as a hosted external identity provider. CloudflareBase wraps it into a Cloudflare-native primitive: each project gets its own AuthAgent Durable Object with embedded SQLite, so users, sessions, roles, permissions, signing keys, and auth configuration live per project.
That auth agent provides:
- email/password auth;
- social sign-in when Google/GitHub credentials are configured;
- guest/anonymous-style flows;
- cookie sessions for browsers;
- bearer tokens for non-browser clients;
- project-signed JWTs for the database and storage agents;
- JWKS/config endpoints;
- roles and permission claims;
- optional auth-event analytics.
So, does it replace the others?
| Tool | Can CloudflareBase auth replace it? | Practical answer |
|---|---|---|
| Firebase Auth | Sometimes | Yes for Cloudflare-native apps that want open-source, per-project auth in their own Cloudflare account. No if you depend on Firebase’s mature managed identity ecosystem, broad SDK coverage, phone auth, enterprise support, or existing Firebase integrations. |
| Logto | Sometimes | Logto is a dedicated identity platform with OIDC/OAuth product depth. CloudflareBase auth is better when you want auth embedded into the CloudflareBase backend platform. Logto is stronger when identity itself is the product boundary across many apps and protocols. |
| PocketBase Auth | Sometimes | PocketBase is simpler and excellent for a single self-contained VPS/SQLite app. CloudflareBase is better when you want Cloudflare edge deployment, Durable Object isolation, and auth tied to its database/storage agents. |
My short take: CloudflareBase auth can replace Firebase Auth, Logto, or PocketBase Auth for the right app, but it does not universally supersede them.
It is strongest when you are already buying into the CloudflareBase platform: Cloudflare Workers, Durable Objects, D1, R2, realtime database, storage, service keys, and dashboard management. If all you need is standalone identity, Logto or another dedicated IdP may be cleaner. If all you need is a tiny local app, PocketBase remains simpler.
How does CloudflareBase simplify self-hosting Better Auth?
If you use Better Auth directly, you still need to decide where it runs, where its database lives, how sessions and signing keys are stored, how roles map to the rest of your backend, how your database/storage APIs verify users, and how you expose an admin/operator surface safely.
CloudflareBase packages those decisions into its auth agent.
Instead of wiring Better Auth manually into each app, CloudflareBase gives every project an AuthAgent Durable Object with embedded SQLite. That agent becomes the project’s identity home: users, sessions, roles, permissions, auth settings, signing keys, JWTs, and state sync live behind one Cloudflare-native boundary.
The practical simplification is:
| If self-hosting Better Auth yourself | With CloudflareBase |
|---|---|
| Pick and operate a database adapter | Auth data lives in per-project Durable Object SQLite |
| Wire auth routes into your app | Auth agent exposes the Better Auth-compatible route surface |
| Design role/permission claims | Roles and permissions are part of the auth agent model |
| Build JWT/JWKS plumbing for other services | Project-signed JWTs and JWKS/config endpoints are built in |
| Connect auth to database/storage access | DB and storage agents can verify the project’s auth tokens |
| Build admin screens for users/sessions/roles | The CloudflareBase console includes auth management pages |
| Decide how to isolate tenants | Each project maps to its own auth Durable Object |
| Deploy and scale the auth runtime | It runs as a Worker/Durable Object in your Cloudflare account |
So CloudflareBase does not make Better Auth disappear. It makes Better Auth operationally packaged for a Cloudflare backend platform.
The tradeoff is that you are no longer just “self-hosting Better Auth”; you are adopting CloudflareBase’s architecture: Workers, Durable Objects, service bindings, and its project model. For a Cloudflare-native Firebase alternative, that is useful. For one small app that only needs login, using Better Auth directly may still be simpler.
Does CloudflareBase replace Supabase?
Not directly.
Supabase is PostgreSQL-centered. That makes it more natural for traditional relational schemas, cross-table joins, SQL reporting, and existing Postgres tooling.
CloudflareBase is Durable Object centered. That makes it more Cloudflare-native and strongly isolated per project/collection/table, but SQL is intentionally scoped and joins are handled through eventually consistent views.
Does CloudflareBase replace Firebase?
It is clearly inspired by the Firebase product shape: auth, database, realtime, remote config, storage, hosting, and SDKs.
The difference is ownership and architecture. CloudflareBase is Apache-2.0 and can run in your Cloudflare account. Firebase is proprietary and managed by Google.
CloudflareBase is also much younger. I would treat it as promising infrastructure to test carefully, not as a drop-in replacement for a mature production Firebase deployment without due diligence.
What do I need to configure for a successful self-hosted deployment?
At minimum, you need a Cloudflare account, Wrangler login, the pinned Node runtime, and the core Workers/Durable Objects/D1 deployment.
Core setup:
- Node
22.18.0or another supported Node version from the repo’s engine constraints; npx wrangler login;npm run deploy:all;- the dashboard Worker;
- the auth, db, storage, and hosting agent Workers;
- Durable Object migrations from each agent config;
- the dashboard D1 control-plane database;
- service bindings from the dashboard Worker to the agents;
- the rate limit binding configured in the dashboard Worker;
CONSOLE_SETUP_TOKENset as a Worker secret before claiming the console.
For the common optional features, configure:
| Feature | What You Need |
|---|---|
| Storage | Enable R2, create/bind the BUCKET bucket for the storage agent, and keep direct public R2 access off so the Worker enforces project prefixes and access modes. |
| Auth email | send_email binding plus EMAIL_FROM. Without this, email verification/password email flows are limited or unavailable. |
| Social login | GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET and/or GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET, unless configured per project through the console where supported. |
| Auth signing | BETTER_AUTH_SECRET is optional because projects can generate their own signing key, but you can set it if you want to own/rotate the shared deployment secret. |
| Extra browser origins | TRUSTED_ORIGINS when another domain serves your UI or calls the APIs with cookies. The deployment’s own origin is trusted automatically. |
| Analytics charts | Enable Analytics Engine in the Cloudflare dashboard, add the relevant dataset bindings, set WAE_DATASET, and use CF_ACCOUNT_ID plus CF_ANALYTICS_API_TOKEN where reads are needed. |
| Copilot/chat | Workers AI binding and CHAT_MODEL if you want to control the model. The default model is configured in the repo. |
| Hosting apps/functions | Workers for Platforms, dispatch namespace, wildcard route/domain, HOSTING_DOMAIN, DISPATCH_NAMESPACE, CF_ACCOUNT_ID, and CF_HOSTING_API_TOKEN. HOSTING_MASTER_KEY is optional but needed for build-secret encryption features. |
| Git push deploys | A GitHub App setup: GITHUB_APP_ID, GITHUB_APP_SLUG, GITHUB_APP_PRIVATE_KEY, and GITHUB_APP_WEBHOOK_SECRET. Without it, use manual CLI deploys. |
| Error reporting | SENTRY_DSN / PUBLIC_SENTRY_DSN and matching environment vars. Empty values disable reporting. |
The clean self-hosting sequence is: deploy the stack, set CONSOLE_SETUP_TOKEN, claim the console, then progressively enable R2, email, Analytics Engine, Workers AI, and Workers for Platforms only if you need those features.
What is the main security warning?
Do not expose operator routes without an authentication layer.
The agent READMEs make a strong distinction between public product APIs and operator-plane APIs. Public APIs enforce access modes, JWTs, service keys, and project rules. Operator APIs assume the dashboard has already checked the caller.
Also keep DEMO_MODE disabled for private self-hosted installs.
How does this relate to the Cloudflare serverless post?
The Cloudflare serverless post explains the base primitives: Workers, D1, KV, and R2.
CloudflareBase goes further by adding a reusable backend platform on top of Cloudflare primitives: auth, database, realtime, remote config, storage, hosting, CLI, and dashboard.
It is useful if you want a Firebase-like layer. It is probably too much if all you need is one small Worker API with D1.
Comments