Cloudflare Workers
Run City directly on Cloudflare Workers and D1 with @downcity/city, without waiting for a separate edge package.
If you want to deploy Downcity on Cloudflare Workers, the recommended path is not a separate edge package. Wire @downcity/city directly into the Workers runtime.
The public repository includes templates/edge as a developer starter. Downcity's private official Worker implementation lives outside the public repository.
What this path actually solves
The main difference from Node.js is not the HTTP entry. It is the runtime resource model:
- the database usually comes from a binding such as
env.DB - environment values are not just a local
.envfile - the request origin may need to be synchronized into services on every request
- Worker isolates are reused, so runtime cache behavior must be managed explicitly
That is why this is better explained as a guide than as an empty npm package.
The minimum shape
City only needs a Drizzle db object:
import { Federation } from "@downcity/city";
import { drizzle } from "drizzle-orm/d1";
export interface Env {
DB: D1Database;
}
export default {
async fetch(request: Request, env: Env) {
const db = drizzle(env.DB);
const base = new Federation({ db });
await base.health();
return base.handleRequest(request);
},
};The important part is not a helper name. It is that you hand the database to City:
- D1 becomes a db through
drizzle-orm/d1 - D1 is a SQLite dialect, so pass
dialect: "sqlite" raw: env.DBis available to services that need the low-level D1 object- the current request origin can be synchronized before calls that need OAuth callback URLs
Use templates/edge as a starter
The starter implementation in templates/edge/src/index.ts covers the integration details most projects need:
- wrap
env.DBwithdrizzle-orm/d1 - let City initialize the built-in
envandcitiestables - synchronize the current origin before each request so OAuth callbacks and links use the correct domain
- keep registering
AIService, accounts, usage, and payment services the same way as the Node path
For a real project, start from that example and adapt the model catalog, services, and provider keys to your product.
Boundary with the Node path
Worker and Node now use the same mental model: create a Drizzle db, then pass it to new Federation({ db }).
- Node.js local projects commonly use
drizzle-orm/better-sqlite3 - Node.js production deployments can use Drizzle pg
- Workers / D1 use
drizzle-orm/d1
Next
- If you still need the City mental model first, read City
- If you need to manage provider keys, continue with Provider environment
- If you want a complete starter implementation, open templates/edge/src/index.ts