Tools
Builder
Author a new brick by answering a short interview; a deterministic engine generates, tests and installs it.
PreviewThe Builder makes a new brick from a conversation. It interviews you one decision at a time and turns your answers into a typed specification, the BrickSpec. A deterministic engine then generates the brick from that spec.
A language model is used for two narrow jobs: turning free-text answers into small pieces of JSON, and writing the body of one function at a time. Nothing the model writes is accepted until it typechecks and passes the acceptance tests derived from your spec.
Open it at builder.bricowerx.com. Using it currently needs an invite. Browsing the Vault of bricks it has built is open to everyone.
How a brick gets built
- Interview
Each question is a card. Every option lists its pros and cons, and one is marked as recommended. Click an option or type your own answer.
- Specification
The Spec tab fills in as you answer: purpose, architecture, data model, lifecycles, operations, interface and requirements. Approve spec and build unlocks only when the spec passes strict validation.
- Build
The engine scaffolds the brick from templates, asks a model for one function body at a time, and runs every gate. You watch it happen in the Build tab.
- Use
The finished brick gets a page with its files and traced requirements, a live preview, an install kit and a zip download.
The interview
The decisions, in order:
| Decision | What you choose |
|---|---|
| Purpose | One sentence, in your own words |
| Layers | Domain only, or with a UI, a server, or both |
| Persistence | Repository-backed entities, or stateless |
| Data model | The entities and their fields, in your own words |
| Lifecycle | Whether status fields follow declared transitions |
| Operations | What the brick must do |
| Interface | A list, detail or form component |
| Data flow | Props from the host, or a generated server action |
| Permissions | Which host capabilities guard which operations |
| Events | Whether operations emit events the host can react to |
Writing operations precisely
Write an operation as a signature, and it is parsed exactly, with no model involved. The model only writes its examples:
markRead(notificationId): sets status to read, fails with NOT_FOUND
archive(notificationId): sets status to archived, fails with NOT_FOUND or ALREADY_ARCHIVED
listUnread(userId, limit): returns the newest unread notificationsWhat uses no model at all
- clicked choices, and typed answers that clearly match an option;
- the lifecycle, built in the order you declare it;
- the UI component, derived from the data model and operations;
- operations written as signatures.
Other free text goes through one small JSON extraction for that step. The engine fixes the usual small-model mistakes itself: it normalises names to camelCase or PascalCase, coerces loose types ("integer" becomes int), fills in seed rows, and drops examples that still fail. A step that still doesn’t validate after two corrections stays open and tells you exactly what to type.
What the spec must pass
- every operation is covered by a requirement (
REQ-1,REQ-2, …); - every example is checked against the declared types;
- capabilities belong to the host contract;
- domain operations are pure.
The build pipeline
| Stage | What happens |
|---|---|
| 1. Validate | Strict BrickSpec parse |
| 2. Plan | The file set and the list of function slots to fill |
| 3. Scaffold | Templates write the brick into a staging area, outside your app |
| 4. Baseline gates | Every gate runs with every body stubbed. A failure here is an engine bug, and the build stops |
| 5. Implement | One slot at a time: the model writes a body; guard, tsc and tests decide; errors go back, up to 3 tries |
| 6. Verify | All gates on the complete brick |
| 7. Trace | Each REQ-n is linked to the tests that prove it |
| 8. Install | One atomic rename into src/features, plus the host adapter, preview entry, spec and report |
Every build ends in one of three results:
| Result | Meaning |
|---|---|
ok | Every operation is implemented and every requirement is satisfied. |
partial | Some operations are typed NotImplemented stubs and their tests are marked todo. The brick still installs, and the report lists what is missing. |
failed | A structural gate failed. Nothing is written. |
Gates
| Gate | What it enforces |
|---|---|
| Builder harness | Paths stay inside the brick, no secrets, no aliased imports, explicit process.env.NAME reads, a single module |
| brick-lint (R1–R6) | Relative imports only, nothing escapes the brick, no dynamic imports, ui/ and server/ kept apart |
| Contract hash (R8) | The vendored host/contract.ts is byte-identical to the host contract |
| TypeScript | The brick typechecks under the strictest tsconfig |
| Tests (R12) | The generated acceptance and lifecycle tests pass, and the brick ships them |
The live build view
The Build tab streams the engine’s events and shows them as sheets that fill in while it works:
| Sheet | Shows |
|---|---|
| Work order | The eight stages and how long each took |
| Blueprint | The planned file tree; files light up as they are written |
| Drafting | The file being written right now, with syntax highlighting |
| Operations | Each slot with its attempts, the model used and the repair messages |
| Inspection | Each gate with its result, timing and pass / fail / todo counts |
| Requirements | Every REQ-n, ticked as its tests pass |
Builds can be replayed. Reload the page, or open /builder?build=<id>, to reconnect and replay a build from the start.
Using a generated brick
| Where | What for |
|---|---|
/bricks/<name> | Files, traced requirements, gate re-runs, and the ports, capabilities, env vars and packages the brick uses |
| Install kit | Copy-ready brico capture, brico add and verification commands, a wiring snippet and a manifest preview |
| Download | A zip with the brick, its host adapter, spec, build report, manifest preview and INSTALL.md |
/preview/<name> | The component in a neutral host, and a playground that runs the real operations on in-memory data |
The brick has no imports outside its own folder, so the simplest install is to copy it. To put a Builder brick into your own Next.js app:
- Get the files
Download the zip from the brick’s page. It contains
<name>/(the brick),host-adapter/, the spec, the build report and anINSTALL.mdwritten for that brick. - Install the brick
Copy
<name>/tosrc/features/<name>/. Or, to version it, capture it into your Vault and add it with the commands from the install kit:bash brico capture <name> -p src/features/<name> --module-version 0.1.0 -y # where the brick is brico add <name> -y # in the target app - Wire it to your app
Copy the
host-adapter/files into your own composition folder, such assrc/brico/, and connect them to your auth, routing, translations and storage. This is the one file per brick that knows about your app. - Verify
bash npx vitest run src/features/<name>The brick ships its own tests and an in-memory repository, so they pass with no database.
Safety
- Static guard. Model-written code is checked before it runs. Imports,
require,process, network access, timers,eval, the clock and randomness are rejected. - Isolated tests. Tests run in a child process with no API keys in its environment and a hard timeout.
- Staging. Bricks are built outside the app. The app only sees a brick after it has passed every gate.
- No overwrites. An existing brick is never replaced.
- Access and limits. Invite-only access, per-person rate limits and request size checks. The shared public demo allows 3 builds an hour and 40 interview steps every 10 minutes per person.
Running your own Builder
The Builder runs its engine inside a long-lived Next.js server, because builds take minutes and run tsc and vitest. It can’t run on serverless hosting. Locally:
cd apps/workbench
npm install
cp .env.example .env.local # add at least one provider key
npm run dev # http://localhost:3000/builderRequires Node.js 20 or later. It only uses free model tiers, and any key you add becomes an automatic fallback. A local model through Ollama keeps it working when every cloud tier is rate-limited. All variables are in Configuration.
Current limits
- The Builder creates new bricks only. Editing an existing brick through its spec isn’t supported yet.
- Generated bricks target Next.js.
- Free-tier models vary. An operation the model can’t implement within its budget is left as a typed stub and reported. The brick is then
partial, never silently wrong.