brick.ts

Configuration File

Set the entry, paths and the dev, build, gen and lint settings once in brick.config.ts.

llms.txt

brick.config.ts holds project and tooling settings: where the app and its services are, what the CLI generates, and how brick dev, brick build and brick lint run. Without it you repeat flags in every script, such as brick dev src/app.ts --client _brick/contract.ts --frontend '…'.

The file is optional. Without one, every command behaves as it did before the file existed.

brick.config.ts
import { defineConfig } from "@brickkit/cli";

export default defineConfig({
  entry: "src/app.ts", // default export is the BrickApp
  services: "src/services", // scanned for *.action.ts, *.command.ts, …
  generated: "_brick", // services.gen.ts and contract.ts go here

  client: {
    output: "_brick/contract.ts", // brick gen client; brick dev keeps it current
  },
  openapi: {
    output: "openapi.json", // brick gen openapi
  },

  dev: {
    port: 4000,
    frontend: "vite --host localhost --port 5178 --strictPort",
    dashboard: { port: 4001, historyDays: 7 }, // or false
  },

  build: {
    outdir: "dist/brick",
    aot: true,
  },

  dashboard: {
    extension: "src/dashboard/index.tsx",
    theme: { light: { primary: "oklch(0.55 0.2 260)" } },
  },

  lint: {
    presets: ["recommended", "layout"],
    rules: { "brick/test-colocated": "warn" },
    ignore: ["src/legacy/**"],
  },
});

With this file, the scripts shrink to the command names:

package.json
{
  "scripts": {
    "dev": "brick dev",
    "build": "brick build",
    "gen": "brick gen",
    "lint": "brick lint"
  }
}

Every key

Paths are relative to the folder that holds brick.config.ts.

KeyDefaultReplacesUsed by
entrysrc/app.tsthe [entry] argumentdev, start, worker, build, gen, info, lint
servicessrc/servicesnewthe services manifest, layout rules
generated_bricknewservices.gen.ts, and the default contract.ts of brick gen client
client.outputnone (no client)dev --client, gen client --outputdev, gen client
openapi.outputstdoutgen openapi --outputgen openapi
dev.port4000dev --portdev
dev.frontendnonedev --frontend (requires client.output)dev
dev.dashboard{} (on)--dashboard-port, --history-days, --no-dashboarddev; false turns the dashboard off
build.outdirdist/brickbuild --outdirbuild
build.aottruebuild --no-aotbuild
build.requestLoggingtruebuild --no-request-loggingbuild; only true is accepted, set requestLogging in brick()
dashboard.extensionnonenewdev, build: the dashboard extension entry
dashboard.themebuilt-in tokensnewdashboard and workflow inspector colours, radius (radius) and fonts (fonts.sans, fonts.mono), per scheme (light, dark)
lint.presets["recommended"]newbrick lint, the ESLint and oxlint plugin
lint.rules{}newper-rule "error", "warn" or "off", except rules that are always errors
lint.ignore[]newglob patterns skipped by every rule

Rules for the file

Precedence. A CLI flag wins over an environment variable (PORT), which wins over the config file, which wins over the default. Existing scripts keep working unchanged: brick dev src/app.ts --port 5000 still serves src/app.ts on 5000. Flags that can only switch something off, such as --no-aot and --no-dashboard, win when given; otherwise the config decides. A --dashboard-port or --history-days flag turns the dashboard back on when the config sets dev.dashboard: false.

Location. Brick looks for brick.config.ts in the working directory and its parents. In a monorepo, --config path/to/brick.config.ts picks one explicitly; every command takes it. With a config file, a bare brick runs brick dev, and a bare brick gen writes the services manifest, then the client contract and OpenAPI document when client.output and openapi.output are set.

Validation. defineConfig gives types in the editor, and the CLI validates the file when it loads it. An unknown key, a bad type, or dev.frontend without client.output fails with the key's path:

brick.config.ts: dev.dashboard.port must be a port number

Dev dependency. defineConfig comes from @brickkit/cli, a dev dependency, so the config never ends up in the server bundle.

Lint reads the same file. brick lint uses lint and the paths above. The ESLint and oxlint plugin reads it through brick.configs.fromProject(), so presets and paths are set in one place. See Lint.

What stays out of the config

Runtime behaviour stays in brick() in app.ts: prefix, docs, telemetry, events, the socket broker, deps. The app must run the same however it's started, including from tests that import it directly.

Secrets never go here. Read them through secrets; the no-env-outside-secrets lint rule enforces it.