Use when creating a new entity/table in Bknd. Covers entity definition with em() and entity(), primary key configuration, field basics, UI creation via admin panel, and code-first approach with type safety.
npx claudepluginhub cameronapak/bknd-expert --plugin bknd-research-skillsThis skill uses the workspace's default tool permissions.
Create a new entity (database table) in Bknd. Entities are the foundation of your data model.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Create a new entity (database table) in Bknd. Entities are the foundation of your data model.
npx bknd create or existing project)bknd package installednpx bknd runhttp://localhost:1337 (default port)posts, users, comments)After entity creation, you're taken to the field editor:
first_name, created_at)Click Sync Database to apply changes to the actual database.
import { em, entity, text, number, boolean, date, enumm, json } from "bknd";
Create your entity within em():
const schema = em({
posts: entity("posts", {
title: text().required(),
content: text(),
published: boolean({ default_value: false }),
view_count: number({ default_value: 0 }),
}),
});
Default is auto-incrementing integer. For UUID:
const schema = em({
posts: entity("posts", {
title: text().required(),
}, {
primary_format: "uuid",
}),
});
Enable type-safe queries:
const schema = em({
posts: entity("posts", {
title: text().required(),
content: text(),
}),
});
// Extract and declare types
type Database = (typeof schema)["DB"];
declare module "bknd" {
interface DB extends Database {}
}
import { App } from "bknd";
const app = new App({
data: schema,
// ... other config
});
import { App, em, entity, text, number, boolean, date } from "bknd";
const schema = em({
users: entity("users", {
email: text().required().unique(),
name: text(),
active: boolean({ default_value: true }),
}),
posts: entity("posts", {
title: text().required(),
content: text(),
published: boolean({ default_value: false }),
published_at: date(),
}),
});
type Database = (typeof schema)["DB"];
declare module "bknd" {
interface DB extends Database {}
}
const app = new App({
data: schema,
});
export default app;
| Convention | Example | Notes |
|---|---|---|
| Plural | users, posts | NOT user, post |
| Lowercase | blog_posts | NOT BlogPosts |
| snake_case | user_profiles | NOT userProfiles |
Every entity automatically includes:
| Field | Type | Description |
|---|---|---|
id | integer/uuid | Primary key (format depends on config) |
Note: For created_at/updated_at, use the timestamps plugin or add manually:
entity("posts", {
title: text().required(),
created_at: date({ default_value: "now" }),
updated_at: date(),
})
Error: Entity "posts" already defined
Fix: Each entity name must be unique within em(). Check for duplicates.
Error: Invalid entity name
Fix: Use lowercase letters, numbers, and underscores only. Must start with letter.
// ✅ Valid
entity("posts", { ... })
entity("user_profiles", { ... })
entity("blog_posts_2024", { ... })
// ❌ Invalid
entity("Posts", { ... }) // No uppercase
entity("2024_posts", { ... }) // Can't start with number
entity("post-items", { ... }) // No hyphens
Problem: Created entity in code but table doesn't exist in database.
Fix: Ensure you're using the schema in your App config:
const app = new App({
data: schema, // Must pass schema here
});
Then restart the server - Bknd auto-syncs on startup.
Problem: api.data.readMany("posts", ...) has no type hints.
Fix: Add type declaration:
type Database = (typeof schema)["DB"];
declare module "bknd" {
interface DB extends Database {}
}
// After app starts, verify entity exists
const api = app.getApi();
const result = await api.data.readMany("posts");
console.log(result); // Should return { data: [] } for empty entity
npx bknd debug routes
# Should show /api/data/posts endpoints
DO:
primary_format: "uuid" for distributed systemsDON'T:
user instead of users)