Custom Code Workflow
> The fastest Brickr custom code loop is: edit locally, test locally, sync shared assets, publish to dev, validate in the Builder, then promote to prod.
This page focuses on the practical authoring loop rather than the API surface. If you need command syntax or SDK references, read CLI and SDK first.
Recommended daily loop
1. Run brickr dev. 2. Edit a node in src/nodes. 3. Watch the local output, logs, and generated test values. 4. If you changed enums, structures, or secrets, run brickr assets sync. 5. Publish with brickr deploy dev. 6. Open the Builder and test the dev version of the node in a real flow. 7. Promote with brickr deploy prod when the behavior is ready for production.
Project conventions that matter
File naming
Brickr only discovers node files that match:
src/**/*.br.tssrc/**/*.br.js
If you create src/nodes/send-email.ts, Brickr ignores it. If you create src/nodes/send-email.br.ts, Brickr loads it.
One node per file
Keep each file focused on one default-exported node definition. This keeps selector matching, source control, and debugging simple.
Stable nodeKey
Treat nodeKey like an API name. You can rename the Builder label later, but changing nodeKey creates a new identity from Brickr's point of view.
Local authoring
Start watch mode
brickr dev
This gives you a terminal loop that:
- scans the current project for
.br.ts/.br.jsfiles - runs each node locally
- prints generated inputs
- prints returned output
- shows any
ctx.log(...)calls - reruns on file changes
For focused work on one node:
brickr dev my-node
Use the most specific selector you have, especially once the project grows.
Write code for the deployed runtime, not only for local dev
brickr dev is convenient because it runs on your machine, but the deployed contract is stricter. When you write code nodes, optimize for the cloud runtime first:
- assume Worker-style execution, not a Node.js server
- assume no direct access to the raw execution-engine
env - assume workspace secrets must come through
ctx.secret(...) - assume shared schemas should come through Brickr enums and structures
This prevents the classic mistake where code works in local dev only because it accidentally depends on a local-only environment detail.
If you plan to call external services from code, validate that node in the workspace dev channel early instead of assuming that anything which runs locally is automatically portable.
Portable code checklist
Before publishing, the safest custom code node looks like this:
- all pins are declared explicitly
- output keys exactly match the declared outputs
- secrets are read via
ctx.secret(...) - shared object types use
t.struct(...) - shared enum values use
t.enumValue(...) brickr.config.tscontains the matching enum / structure / secret definitions- the node does not depend on Node.js-only APIs
If you want the Builder, the SDK, and the runtime to agree with each other, the node definition and brickr.config.ts should be treated as one unit in code review.
Designing local-friendly nodes
Because brickr dev auto-generates inputs, your nodes are easier to test if you define sensible defaults:
inputs: {
baseUrl: t.string().default("https://example.com"),
timeoutMs: t.number().default(5000),
enabled: t.boolean().default(true)
}
Benefits:
- local runs are immediately meaningful
- output is easier to inspect
- the Builder gets better default behavior too
If a pin has no default, Brickr falls back to a type-based placeholder. For complex nodes, that often means {}, [], or null, which may not be enough for a useful run.
If a node depends on specific object shape, define that structure in brickr.config.ts and set a realistic input default where possible.
Handling secrets cleanly
Use workspace secrets for real credentials and local environment variables for brickr dev.
Typical pattern:
1. Create the workspace secret:
brickr secret create
2. Reference it in code:
const apiKey = ctx.secret("OPENAI_API_KEY");
3. Export it from brickr.config.ts if you want the secret definition to be code-managed:
import { defineSecret } from "@brickr/sdk";
export default {
projectName: "main",
enums: [],
structures: [],
secrets: [
defineSecret({
name: "OPENAI_API_KEY",
description: "Workspace key for AI requests"
})
]
};
4. Set the matching environment variable locally before running brickr dev.
If the environment variable is missing, local execution fails fast instead of silently returning bad output.
Managing shared types in code
If multiple nodes need the same enum or structure, keep it in brickr.config.ts and sync it explicitly:
brickr assets sync
Do this whenever you change:
- enum values
- structure fields
- code-managed secret definitions
brickr status warns when Brickr detects drift between code-managed assets in your workspace and the local config.
This is what makes the docs, Builder, and runtime line up cleanly for both humans and AI agents. Instead of guessing object shapes or secret names from free text, an agent can load:
- the node pin contract
- the synced enum definitions
- the synced structure definitions
- the named secret definitions
and generate correct code against those sources of truth.
Publish flow
Publish to dev first
brickr deploy dev
This uploads the latest local node bundles and manifests to your workspace dev channel. At this point the Builder can use and test the latest version.
Validate in the Builder
After a dev publish:
1. Open the Builder 2. Find the node by category or search 3. Add it to a real route or function 4. Test the surrounding flow 5. Verify real inputs, outputs, and runtime behavior
Local tests are fast, but Builder tests still matter because they exercise the node inside an actual Brickr flow.
Promote to production
brickr deploy prod
This promotes the current dev versions to production. Do not skip the dev step if you care about stable rollout discipline.
Useful inspection commands
See what is deployed
brickr status
Good for:
- confirming the linked workspace
- checking dev/prod versions
- spotting asset drift
List node versions only
brickr nodes list
Useful when you want the compact deployed-state view without the rest of the project metadata.
Common failure cases
"No workspace connected. Run: brickr init"
The current directory is not linked. Run:
brickr init
or reconnect an existing project with:
brickr link
"No .br.ts / .br.js nodes found"
Brickr did not find any matching node files. Check:
- the file is inside
src/ - the filename ends in
.br.tsor.br.js - the module default-exports
defineCodeFunctionNode(...)
Missing local secret
If ctx.secret("NAME") fails during brickr dev, set the matching environment variable:
export NAME=value
brickr dev
In deployed code, do not replace this with process.env.NAME. The correct production path is still ctx.secret("NAME").
Node selector is ambiguous
Your brickr dev [node] selector matched more than one node. Use the exact nodeKey or a more precise filename.
Asset drift warning
If brickr status warns about drift, Brickr detected that a code-managed enum, structure, or secret was changed in the workspace outside your current local source. Re-sync the intended local state with:
brickr assets sync
Local code works, deployed code does not
Usually this means the node accidentally depended on something local-only. Check:
- did you use
process.envinstead ofctx.secret(...)? - did you assume access to raw Worker bindings or internal
envvalues? - did you depend on Node.js-only APIs?
- did you depend on runtime-heavy globals such as
fetch()without validating the deployed dev version? - did you change enums or structures locally without syncing them?
Team workflow recommendations
- Keep one Brickr project per logical node package or workspace.
- Review node source and
brickr.config.tstogether in pull requests. - Use local defaults so teammates can run
brickr devwithout reconstructing every input manually. - Keep secret names stable across environments.
- Promote to prod only from tested dev versions, not directly from untested local edits.
- Prefer explicit, machine-readable contracts over implicit conventions so AI tooling can generate correct nodes consistently.
A complete example sequence
npx brickr
brickr dev
brickr assets sync
brickr deploy dev
brickr status
brickr deploy prod
brickr update
What's next?
| Topic | Description | |-------|-------------| | Overview | Architecture and lifecycle | | CLI | Command reference | | SDK | Node and asset authoring API |