Compose vs. generate
Two ways the agent ships a project. Compose mode picks from a closed catalog of blocks. Generate mode writes real React code. The agent decides which one to use based on your prompt; you can't pick directly. This page explains the difference so you can write prompts that land in the mode you want.
At a glance
| Compose | Generate | |
|---|---|---|
| Best for | CRUD trackers, lists, journals | Custom UI, charts, canvas, real-time |
| How it works | Picks blocks from @atriux/blocks | Writes React, compiles via esbuild, sandboxed iframe |
| Build time | ~30-45s | ~60-120s |
| Build cost | 5-15 credits | 15-35 credits |
| Persistence model | project_items JSONB | useProjectData per-(project, user) blob |
| Data entry | ChatBlock (always) | Custom UI + useDataAgent hook |
| Visual style | Locked editorial — same as the rest of the platform | Closed primitives + creator's arrangement |
Compose mode in detail
Compose-mode projects are JSON config — an array of block instances picked from a closed registry. Each block is a server-rendered React component that reads from project_items. The agent's job is to:
- Pick a name + slug + description (
set_metadata) - Declare the data shape (
set_schema— fields, types, options) - Pick the right blocks in the right order (
add_blockcalls) - Finalize (
finish_compose_project)
The standard block pattern for a CRUD project:
HeroBlock — page header
ChatBlock — natural-language data entry (every project)
StatBlock — top-level metrics (totals, counts)
ChartBlock — pie / bar / line for visual breakdown
ItemListBlock — recent rowsThe agent's system prompt has the full block catalog in context. It picks blocks, picks props (e.g. which field to plot), and stops.
What compose-mode CAN'T do
- Custom canvas drawing (no canvas block)
- Webcam / microphone access
- Custom interactive UI (drag-drop, sliders, custom keyboards)
- Real-time data sync between users
- Anything the closed block catalog doesn't cover
When you ask for one of these, the agent should switch to generate mode. If the agent picks compose anyway and produces something half-baked, you can rebuild with a more explicit prompt.
Generate mode in detail
Generate-mode projects are real React code, written by the agent. The flow:
- The agent picks a name + slug + description.
- It calls
write_filerepeatedly to build upApp.tsx(the entry point) plus any helper files. - It calls
validate_projectto compile via esbuild. If the compile fails with errors, it reads the errors, callsread_fileto see the offending file, and writes a fix. - Once
validate_projectreturns "ok", it callsfinish_generate_project. This compiles a final time, stores the source files inproject_files, and stores the compiled JS bundle on theprojectsrow.
The runtime surface
Agent code runs inside a sandboxed iframe (sandbox="allow-scripts", no allow-same-origin). It can only import three modules:
react— hooks, JSXreact-dom— only via the synthetic mounting layer the platform injects@atriux/runtime— the closed SDK for talking to the platform (auth, persistence, theme, chat)
Any other import fails compilation. There's no fetchto off-platform URLs (CORS-blocked from the iframe's null origin), no third-party packages, no localStorage. Everything goes through the runtime SDK.
Forbidden patterns (statically analyzed)
The compile step rejects:
eval,new Function(...),Function('...')- Dynamic
import(<expression>)with non-literal arguments require()- Direct
window.parent,top.location
These are belt-and-suspenders alongside the iframe sandbox — the sandbox is the actual security guarantee, but the lint catches obvious abuse before it hits compilation.
Writing prompts that land in the right mode
Use compose-mode language for:
- "Track the X I'm doing/planning/contacting"
- "A list of Y with these fields"
- "Daily journal" / "Reading list" / "Lead tracker"
- "Show me [stats / charts] of my data" — these are also compose, since StatBlock and ChartBlock cover them
Use generate-mode language for:
- "Webcam / camera / video" (anything visual via getUserMedia)
- "Drag-and-drop", "keyboard shortcuts", "custom interactions"
- "Stopwatch", "timer", "clock" (real-time UI)
- "Calculator", "simulator", "animation"
Next: Block catalog →