brick.ts

Quickstart

Build and run an in-memory SQLite CRUD service in less than 5 minutes.

Star on GitHub
llms.txt

This guide gets a runnable Brick-TS service running locally with Bun and SQLite in less than five minutes.

1. Install Dependencies

Initialize a new Bun project and install @brickkit/core, @brickkit/crud, and @brickkit/cli:

mkdir my-brick-app && cd my-brick-app
bun init -y
bun add @brickkit/core @brickkit/crud @brickkit/cli

2. Create the Application

Create src/app.ts with a SQLite table, a database handle, and a CRUD resource:

src/app.ts
import {
  brick,
  defineDatabase,
  defineService,
  sqliteTable,
  syncSchema,
  text,
} from "@brickkit/core";
import { crud } from "@brickkit/crud";

// Define the database table with Drizzle
export const pages = sqliteTable("pages", {
  id: text("id")
    .primaryKey()
    .$defaultFn(() => crypto.randomUUID()),
  title: text("title").notNull(),
  content: text("content"),
});

// Configure an in-memory database for immediate development
const database = defineDatabase({ tables: { pages } });
export const pagesService = defineService("pages", { database });

// Register the CRUD resource. CRUD requires an explicit access policy.
pagesService.resource({ name: "page", table: pages, id: pages.id }).use(
  crud({
    access: "public",
    fields: {
      id: { read: true, filter: ["eq"] },
      title: {
        read: true,
        create: true,
        update: true,
        filter: ["eq", "contains"],
        sort: true,
      },
      content: { read: true, create: true, update: true },
    },
  }),
);

// Prepare the in-memory SQLite table schema
syncSchema(pagesService);

// Export the default application for the brick CLI or embedded runtime
export const app = brick({
  services: [pagesService],
  title: "Pages API",
  version: "1.0.0",
});

export default app;

Schema

These columns match the Drizzle tables in the example. Defaults marked as application defaults run in Drizzle, rather than in SQL.

Table Name: pages

FieldTypeDescription
idtextRow identifier. PK Default: crypto.randomUUID() (application)
titletextDisplay title.
contenttextPage content. Optional

3. Start the Server

Run the development server with live reload using the brick CLI:

bunx brick dev src/app.ts --port 4000

The CLI loads your entry, then prints the registered services and the route each action is mounted on:

[Brick-TS] Loading application entry: /path/to/my-brick-app/src/app.ts

🧱 Brick-TS Development Server
   Registered Services: 1
   • pages (8 actions)
     -> POST   /api/page/query
     -> GET    /api/page/:id
     -> POST   /api/page
     -> PATCH  /api/page/:id
     -> DELETE /api/page/:id
     -> POST   /api/page/find-one
     -> POST   /api/page/count
     -> POST   /api/page/exists

⚡ API Gateway running on: http://localhost:4000
🩺 Health check:        http://localhost:4000/_health
🗺️ Architecture graph:  http://localhost:4000/_brick/services

CRUD routes are mounted under the resource name (page), not the service name. The action names are still page.list, page.get, page.create, and so on.

brick dev imports your entry to register its services, then builds its own server with the default /api prefix. Options you pass to brick() in the entry (such as title) don't apply under brick dev. Without --port, the port comes from the PORT environment variable, then defaults to 4000.

4. Test the API Endpoints

Execute HTTP requests against the generated CRUD endpoints. Successful calls return 200 with the JSON result.

Create a Record

curl -X POST http://localhost:4000/api/page \
  -H "Content-Type: application/json" \
  -d '{"title": "First Page", "content": "Welcome to Brick-TS!"}'

Response:

{
  "id": "e379b38c-8f19-485a-a71c-3b91ef5246a4",
  "title": "First Page",
  "content": "Welcome to Brick-TS!"
}

List Records with Filtering

page.list is a POST to /api/page/query. The body is validated against the filter operators and sortable fields you enabled in fields:

curl -X POST http://localhost:4000/api/page/query \
  -H "Content-Type: application/json" \
  -d '{
    "where": {
      "field": "title",
      "op": "contains",
      "value": "First"
    },
    "orderBy": [{ "field": "title", "direction": "asc" }],
    "limit": 10
  }'

Response:

{
  "items": [
    {
      "id": "e379b38c-8f19-485a-a71c-3b91ef5246a4",
      "title": "First Page",
      "content": "Welcome to Brick-TS!"
    }
  ],
  "limit": 10,
  "offset": 0
}

View Interactive API Documentation

Visit the interactive API documentation and spec endpoints provided out of the box. They're mounted at the root, not under the /api prefix:

  • Scalar API Docs: http://localhost:4000/docs
  • Swagger UI: http://localhost:4000/swagger
  • OpenAPI 3.1 Spec: http://localhost:4000/openapi.json
  • Service Architecture Graph: http://localhost:4000/_brick/services
  • Health Check: http://localhost:4000/_health