bknd-local-setup
Local Development Setup
Set up a Bknd local development environment from scratch.
Prerequisites
- Node.js 18+ or Bun 1.0+
- npm, yarn, pnpm, or bun package manager
- Terminal/command line access
When to Use UI Mode
- Browsing admin panel at
http://localhost:3000/admin - Exploring entities and data visually
- Testing auth flows manually
Note: Initial project setup requires CLI/code.
When to Use Code Mode
- Creating new Bknd project
- Configuring database connection
- Defining schema
- Running development server
- All initial setup tasks
Code Approach
Step 1: Create New Project (Interactive)
Quickest way to start:
# Interactive project creation
npx bknd create my-app
# Follow prompts:
# - Project name
# - Database type (SQLite recommended for local dev)
# - Include example schema?
This creates project structure with:
bknd.config.ts- Main configurationpackage.json- Dependencies.env- Environment variables template
Step 2: Install Dependencies
cd my-app
# npm
npm install
# bun (faster)
bun install
# pnpm
pnpm install
Step 3: Run Development Server
# Default (port 3000, file-based SQLite)
npx bknd run
# In-memory database (fastest for prototyping, data lost on restart)
npx bknd run --memory
# Custom port
npx bknd run --port 8080
# Don't auto-open browser
npx bknd run --no-open
# Specify runtime explicitly
npx bknd run --server bun
npx bknd run --server node
Server starts at http://localhost:3000 with:
- API:
/api/data/*,/api/auth/*,/api/media/* - Admin UI:
/admin
Alternative: Manual Setup
Step 1: Initialize Package
mkdir my-bknd-app && cd my-bknd-app
npm init -y
npm install bknd
Step 2: Create Config File
Create bknd.config.ts:
import type { CliBkndConfig } from "bknd";
import { em, entity, text, boolean } from "bknd";
// Define schema
const schema = em({
todos: entity("todos", {
title: text().required(),
done: boolean(),
}),
});
// Register types
type Database = (typeof schema)["DB"];
declare module "bknd" {
interface DB extends Database {}
}
export default {
app: (env) => ({
connection: {
url: env.DB_URL ?? "file:data.db",
},
schema,
}),
} satisfies CliBkndConfig;
Step 3: Create Entry File (Optional)
For programmatic control, create index.ts:
import { serve } from "bknd/adapter/bun";
import { em, entity, text, boolean } from "bknd";
const schema = em({
todos: entity("todos", {
title: text().required(),
done: boolean(),
}),
});
serve({
connection: { url: "file:data.db" },
config: {
data: schema.toJSON(),
},
});
Run with:
# Bun
bun run index.ts
# Node (requires tsx or ts-node)
npx tsx index.ts
Runtime Adapters
Bun (Recommended for Speed)
import { serve } from "bknd/adapter/bun";
serve({
connection: { url: "file:data.db" },
});
Node.js
import { serve } from "bknd/adapter/node";
serve({
connection: { url: "file:data.db" },
});
Framework Integrations
Next.js:
// app/api/bknd/[[...bknd]]/route.ts
import { createHandler } from "bknd/adapter/nextjs";
export const { GET, POST, PUT, DELETE, PATCH } = createHandler(config);
Astro:
// src/pages/api/[...bknd].ts
import { createHandler } from "bknd/adapter/astro";
export const ALL = createHandler(config);
React Router (Remix):
// app/routes/api.$.tsx
import { createHandler } from "bknd/adapter/react-router";
export const loader = createHandler(config);
export const action = createHandler(config);
CLI Options Reference
| Option | Description | Default |
|---|---|---|
-p, --port <port> |
Server port | 3000 |
-m, --memory |
Use in-memory database | - |
--server <server> |
Runtime: node or bun |
Auto-detected |
--no-open |
Don't auto-open browser | Opens by default |
-c, --config <path> |
Config file path | Auto-detected |
--db-url <url> |
Database URL override | - |
Config File Detection
Bknd auto-detects config files (in order):
bknd.config.tsbknd.config.jsbknd.config.mjsbknd.config.cjsbknd.config.json
Project Structure
Recommended Layout
my-bknd-app/
├── bknd.config.ts # Main configuration
├── bknd-types.d.ts # Generated types (run: npx bknd types)
├── .env # Environment variables
├── .dev.vars # Dev-specific overrides (optional)
├── data.db # SQLite file (auto-created)
├── uploads/ # Local media storage (if using local adapter)
└── package.json
Framework Integration Layout
my-nextjs-app/
├── app/
│ ├── api/
│ │ └── bknd/
│ │ └── [[...bknd]]/
│ │ └── route.ts
│ └── admin/
│ └── page.tsx
├── bknd.config.ts
├── bknd-types.d.ts
└── .env.local
Generate TypeScript Types
After defining schema, generate types for IDE support:
# Generate to bknd-types.d.ts (default)
npx bknd types
# Custom output
npx bknd types -o types/bknd.d.ts
# Print to console (debug)
npx bknd types --dump
Database Options for Local Dev
| Database | URL Format | Best For |
|---|---|---|
| In-memory SQLite | :memory: or --memory flag |
Quick prototyping |
| File SQLite | file:data.db |
Persistent local dev |
| LibSQL (Turso) | libsql://your-db.turso.io |
Remote dev database |
In-Memory (Ephemeral)
npx bknd run --memory
Data resets on server restart. Best for rapid prototyping.
File-Based SQLite (Persistent)
npx bknd run
# or explicitly:
npx bknd run --db-url "file:data.db"
Data persists in data.db file.
Reset Database
# Delete SQLite file for fresh start
rm data.db
# Then restart server
npx bknd run
Hot Reload
Schema changes require server restart. Use watch mode:
# Bun
bun --watch index.ts
# Node with nodemon
npx nodemon --exec "npx bknd run"
Debug Commands
# Show internal paths
npx bknd debug paths
# Show all registered routes
npx bknd debug routes
# CLI help
npx bknd --help
npx bknd run --help
Verification
After setup, verify everything works:
1. Server running:
curl http://localhost:3000/api/data
# Should return entity list
2. Admin panel accessible:
Open http://localhost:3000/admin in browser
3. Types generated:
npx bknd types
# Check bknd-types.d.ts created
Common Pitfalls
Config File Not Found
Problem: Config file could not be resolved error
Fix: Ensure config file exists with correct extension:
# Check file exists
ls bknd.config.*
# Or specify explicitly
npx bknd run -c ./bknd.config.ts
Port Already in Use
Problem: EADDRINUSE: address already in use
Fix: Use different port or kill existing process:
# Use different port
npx bknd run --port 3001
# Or find and kill process
lsof -i :3000
kill -9 <PID>
Database Permission Error
Problem: SQLITE_CANTOPEN: unable to open database file
Fix: Ensure write permissions in directory:
# Check permissions
ls -la
# Fix permissions
chmod 755 .
TypeScript Errors with em()
Problem: Type errors when using em() return value
Fix: Remember em() returns schema definition, not EntityManager:
// WRONG - em() is schema builder only
const em = em({ ... });
em.repo("posts").find(); // ERROR
// CORRECT - use api.data for queries
const api = new Api({ url: "http://localhost:3000" });
api.data.readMany("posts");
Bun Not Found
Problem: bun: command not found
Fix: Install Bun or use Node:
# Install Bun
curl -fsSL https://bun.sh/install | bash
# Or use Node runtime
npx bknd run --server node
Windows Path Issues
Problem: File paths not resolving on Windows
Fix: Use forward slashes:
// WRONG
connection: { url: "file:C:\\data\\my.db" }
// CORRECT
connection: { url: "file:C:/data/my.db" }
// or relative
connection: { url: "file:data.db" }
DOs and DON'Ts
DO:
- Use
--memoryflag for quick experiments - Use
file:data.dbfor persistent development - Generate types after schema changes
- Commit
bknd.config.tsto version control - Use
.envfor environment-specific values
DON'T:
- Commit
data.dbto version control (add to.gitignore) - Commit
.envwith secrets (use.env.exampletemplate) - Use in-memory database when you need data persistence
- Forget to restart server after schema changes
- Try to use
em()result as EntityManager
Related Skills
- bknd-env-config - Configure environment variables
- bknd-create-entity - Create entities in your schema
- bknd-client-setup - Set up SDK in frontend
- bknd-debugging - Debug common issues
- bknd-deploy-hosting - Deploy to production
More from cameronapak/bknd-skills
bknd-login-flow
Use when implementing login and logout functionality in a Bknd application. Covers SDK authentication methods, REST API endpoints, React integration, session checking, and error handling.
16bknd-session-handling
Use when managing user sessions in a Bknd application. Covers JWT token lifecycle, session persistence, automatic renewal, checking auth state, invalidating sessions, and handling expiration.
15btca-bknd-repo-learn
Use btca (Better Context App) to efficiently query and learn from the bknd backend framework. Use when working with bknd for (1) Understanding data module and schema definitions, (2) Implementing authentication and authorization, (3) Setting up media file handling, (4) Configuring adapters (Node, Cloudflare, etc.), (5) Learning from bknd source code and examples, (6) Debugging bknd-specific issues
15bknd-protect-endpoint
Use when securing specific API endpoints in Bknd. Covers protecting custom HTTP triggers, plugin routes, auth middleware for Flows, checking permissions in custom endpoints, and role-based endpoint access.
15bknd-file-upload
Use when uploading files to Bknd storage. Covers MediaApi SDK methods (upload, uploadToEntity), REST endpoints, React integration with file inputs, progress tracking with XHR, browser upload patterns, and entity field attachments.
15bknd-deploy-hosting
Use when deploying a Bknd application to production hosting. Covers Cloudflare Workers/Pages, Node.js/Bun servers, Docker, Vercel, AWS Lambda, and other platforms.
14