Create Federation
Initialize the Downcity server-side Federation with the default database and HTTP service.
The server-side runtime class is Federation (also called the Federation in these docs); product clients use the City client to reach it. See Federation and City for the distinction.
The fastest local creation and startup path is:
fed create ./my-fed
cd my-fed
pnpm install
fed deployThe default template uses Node.js and SQLite. fed deploy allocates a port starting at 12314, registers the process in system-level Fed state, and interactively asks you to set an administrator ID and password. The password must be at least 12 characters; only its PBKDF2 digest is stored in the database. fed then uses a time-limited administrator Session Token to inspect and manage the Federation from any directory. To replace lost credentials, run fed deploy --admin-reset; this revokes existing administrator sessions and asks for the new credentials. The rest of this page shows the SDK path for manually embedding the Federation runtime.
Install the packages:
pnpm add @downcity/federation @downcity/database-sqliteThe database is the only thing you need before boot. fed deploy asks for an administrator ID and password; the password is stored as a PBKDF2 digest and later logins receive a session token. DOWNCITY_FEDERATION_TOKEN_SIGNING_KEY and BETTER_AUTH_SECRET are generated automatically. Provider keys are written later through the Admin API or the fed admin workspace:
OPENAI_API_KEY="..."
OPENAI_BASE_URL="https://api.openai.com/v1"Create Federation:
import { Federation } from "@downcity/federation";
import { Database } from "@downcity/database-sqlite";
const database = new Database({ filename: "./data.sqlite" });
const base = new Federation({ database });The default database is stored at:
./data.sqliteUse @downcity/database-sqlite locally. For production PostgreSQL, switch to @downcity/database-postgresql.
For Cloudflare Workers / D1, pass the D1 adapter:
import { Database } from "@downcity/database-d1";
const database = new Database({ binding: env.DB });
const base = new Federation({ database });Federation initializes itself automatically on the first health(), fetch(), table(), or similar runtime call.
If your Federation needs its own business tables, declare them on a Service or service:
import { sqliteTable, text } from "drizzle-orm/sqlite-core";
import { Service } from "@downcity/federation";
const notes = sqliteTable("notes", {
id: text("id").primaryKey(),
title: text("title").notNull(),
status: text("status").notNull(),
});
const notesService = new Service({
id: "notes",
tables: { notes },
});
base.use(notesService);
const table = await base.table("notes.notes");
await table.insert({
id: "note_1",
title: "First note",
status: "draft",
});Tables declared by services use the same database connection as Federation. Regular projects do not need manual table creation.
Start the HTTP service:
import { serve } from "@hono/node-server";
await base.health();
serve({ fetch: (request) => base.fetch(request), port: 3001, hostname: "127.0.0.1" });This service is the shared Federation used by later cities. Management and business data are handled through your own database and city backend for now.