SQLite
Start locally with Bun’s native SQLite driver. Use an in-memory database for examples or a file-backed database for persistence.
- Bun-native driver
- In-memory or file-backed
Small definitions. Production execution.
Your actions, resources, and rules.
Compiled into a backend ready to run on Bun.
01 / THE DEVELOPER SURFACE
Start with direct calls. Expose HTTP when you need it. The same typed definitions power both.
import { defineService, t } from "@brickkit/core";
const users = new Map([["usr_42", { id: "usr_42", name: "Ada" }]]);
export const usersService = defineService("users");
export const getUser = usersService.action({
name: "getUser",
input: t.Object({ id: t.String() }),
execute: ({ input, error }) => {
const user = users.get(input.id);
if (!user) error.NOT_FOUND("User not found");
return user;
},
});import { getUser } from "./services/users";
const user = await getUser({ input: { id: "usr_42" } });
console.log(user);Invoke the same typed action directly in process. These files are the runnable examples/showcase source in this repository.
02 / BUILT TO FIT TOGETHER
A focused set of primitives, built on the TypeScript tools you already know.
Call typed actions directly in process with the same validation and error handling used by HTTP routes.
Compile action handlers and resource plans ahead of request handling, and serve them through Elysia.
Single repository with shared schemas, full TypeScript type safety, and instant jump-to-definition across services.
Expose services over HTTP using the same action definitions you invoke in process.
First-class integration with Better Auth session security and Drizzle ORM pre-compiled query caching.
03 / RESOURCES
Define a Drizzle table and install the CRUD resource plugin. It supplies CRUD routes, list filters, pagination, and typed hooks. Add custom actions for everything beyond CRUD.
/api/comment/queryList/api/comment/:idRead/api/commentCreate/api/comment/:idUpdate/api/comment/:idDeleteActual source from the comments extension. No illustrative APIs.
04 / TYPE SAFETY
TypeBox schemas supply action types and runtime validation. Drizzle tables supply row types and resource shapes. OpenAPI describes the same registered API.
Follow the types05 / ACCESS CONTROL
Resolve a session into service context, authorize custom actions, and scope resource rows to their owner. Connect Better Auth through its session API or bring your own provider.
Configure sign-in checks for protected CRUD routes. Owner scoping complements those checks.
Configure access controlResolve the user and session.
Check access before execution.
Scope records to their owner.
06 / DATABASES
Keep your SQL, table definitions, and migrations. Brick adds services and resources around them.
Start locally with Bun’s native SQLite driver. Use an in-memory database for examples or a file-backed database for persistence.
Connect PostgreSQL with a URL and Drizzle tables. Keep production schema changes in your migration workflow.
07 / EXTENSIONS
Package a table, resource, hooks, and custom actions as a reusable TypeScript module. Import it into a service and register it before building the server.
The comments example is runnable today. Use the same pattern for your own workflows.
Build your first extensionimport {
brick,
defineDatabase,
defineService,
syncSchema,
sqliteTable,
text,
} from "@brickkit/core";
import { commentsTable, comments } from "./extensions/comments";
const pages = sqliteTable("pages", { id: text("id").primaryKey() });
const database = defineDatabase({ tables: { pages, comments: commentsTable } });
syncSchema(database.tables, database.getDb());
await database
.getDb()
.insert(pages)
.values([{ id: "page-1" }, { id: "page-2" }]);
export const pagesService = defineService("pages", { database });
export const page = pagesService
.resource({ name: "page", table: pages, id: pages.id })
.use(comments({ table: commentsTable }));
export const app = brick({ services: [pagesService], requestLogging: false });Standard imports. Standard TypeScript. Your reusable module.
08 / ENDPOINTS
Use raw endpoints when you need direct control over the request, headers, status, or response body.
Render a public page and set its content type in your handler.
Read the original request and apply your provider’s signature checks.
Return a Response with your own headers, status, or streaming body.
09 / TOOLING
See what your definitions become. Work with real output, live contracts, and runnable examples.
Build emits route handlers, Brick IR, and a bundled Bun server. Your callbacks remain TypeScript-authored application logic.
See compiler outputServe generated OpenAPI with Scalar and Swagger views. Export a spec or inspect the registered service architecture.
Explore API documentationThe extension demo exercises compiled routes, CRUD, validation errors, and direct action calls.
Run the example10 / THE FOUNDATION
A backend authoring layer over a familiar runtime and database toolkit.
YOUR NEXT BACKEND STARTS HERE