Setup & Modes
Choose a mode and get bknd running with your app
bknd supports three modes. Each mode determines how your backend is configured and where that configuration lives.
Choose your mode
UI-only (default)
Configure visually via the Admin UI. Config is stored in the database.
Code-only
Define your schema in code with a Drizzle-like API. Config lives in your codebase.
Hybrid
Use the Admin UI in development, export to code for production.
Not sure which to pick?
- UI-only is best for prototyping and small projects. No code needed — configure everything through the dashboard.
- Code-only is best for teams, CI/CD, and version-controlled schemas. You define your data structure programmatically.
- Hybrid gives you the best of both — visual configuration while developing, locked-down code config in production.
You can always change modes later. Start with UI-only if you're exploring.
UI-only mode
This is the default. Run bknd and configure everything through the Admin UI. No setup code required beyond a database connection.
import type { BkndConfig } from "bknd";
export default {
connection: { url: "file:data.db" },
} satisfies BkndConfig;If you want to provide an initial data structure (entities, auth settings, etc.), pass it via config. It will only be applied when the database is empty.
import type { BkndConfig } from "bknd";
export default {
connection: { url: "file:data.db" },
config: {
auth: { enabled: true },
},
} satisfies BkndConfig;In UI-only mode, the config property is only applied on first boot. After that, all changes are made through the Admin UI.
Next step: Pick your framework or runtime integration to wire bknd into your app.
Code-only mode
Define your data structure programmatically with a Drizzle-like API. The Admin UI becomes read-only for configuration — you still use it to manage data.
import { type BkndConfig, em, entity, text, boolean } from "bknd";
import { secureRandomString } from "bknd/utils";
const schema = em({
todos: entity("todos", {
title: text(),
done: boolean(),
}),
});
export default {
connection: { url: "file:data.db" },
config: {
data: schema.toJSON(),
auth: {
enabled: true,
jwt: { secret: secureRandomString(64) },
},
},
options: {
mode: "code",
},
} satisfies BkndConfig;Unlike UI-only mode, the config is applied on every boot. If you change the schema, you may need to sync the database.
Next step: Pick your framework or runtime integration to wire bknd into your app.
Hybrid mode
Use the Admin UI to configure your backend while developing. When you're ready to deploy, export the config and run in code mode for production.
import type { BkndConfig } from "bknd";
import appConfig from "./appconfig.json" with { type: "json" };
export default {
connection: { url: "file:data.db" },
config: appConfig,
options: {
mode: process.env.NODE_ENV === "development" ? "db" : "code",
manager: {
secrets: process.env,
},
},
} satisfies BkndConfig;To export your config, secrets, and types, use the CLI or plugins:
| What | CLI Command | Plugin |
|---|---|---|
| Configuration | bknd config | syncConfig |
| Secrets | bknd secrets | syncSecrets |
| Types | bknd types | syncTypes |
Next step: Pick your framework or runtime integration to wire bknd into your app.
Mode helpers
For code and hybrid modes, bknd provides helper functions that handle syncing, mode switching, and schema validation automatically.
import { code } from "bknd/modes";
import { type BunBkndConfig, writer } from "bknd/adapter/bun";
export default code<BunBkndConfig>({
connection: { url: "file:data.db" },
writer,
isProduction: Bun.env.NODE_ENV === "production",
typesFilePath: "bknd-types.d.ts",
});import { hybrid } from "bknd/modes";
import { type BunBkndConfig, writer, reader } from "bknd/adapter/bun";
export default hybrid<BunBkndConfig>({
connection: { url: "file:data.db" },
writer,
reader,
secrets: await Bun.file(".env.local").json(),
isProduction: Bun.env.NODE_ENV === "production",
typesFilePath: "bknd-types.d.ts",
configFilePath: "bknd-config.json",
});Mode helpers give you:
- Built-in syncing of config, types, and secrets
- Automatic schema syncing in development
- Automatic mode switching (db → code) in production for hybrid
- Skipped config validation in production for faster boot
Further reading
- Framework & runtime integrations — wire bknd into Next.js, Astro, Bun, Cloudflare, etc.
- Database configuration — choose and configure your SQL database
- Configuration reference — full
BkndConfigAPI, plugins, events, and lifecycle hooks