Skip to content

code.scaffold_react_node

The engine behind the Full-stack app generator: given a name, a description, a list of pages and API routes, it writes a real, runnable npm-workspaces monorepo — not a single-file demo.

Schema

Input = {
name: string, // product/project name
description: string, // what the app is for; drives generated copy and sample data
pages?: Array<string | { name: string, path?: string, description?: string }>,
apiRoutes?: Array<string | { method: 'GET'|'POST'|'PUT'|'PATCH'|'DELETE', path: string, description?: string }>,
style?: string, // default 'clean, modern, generous whitespace, one accent colour'
dir?: string, // sub-folder of the workspace to write into
build?: boolean, // default true — npm install + vite build, best effort
buildTimeoutMs?: number, // 10s-10min, default 180000
}
Output = {
dir: string,
files: string[],
pages: Array<{ name: string, path: string, file: string }>,
apiRoutes: Array<{ method: string, path: string, file: string }>,
built: boolean,
previewPath: string | null, // relative path of dist/index.html when the build succeeded
buildLog: string,
contentSource: 'model' | 'placeholder',
costUsd: number,
runSteps: string[],
}

apiRoutes accepts a loose string shorthand too: "GET /api/items" or just "/api/items" (defaults to GET) parses into the structured form.

What actually gets written

A real workspace: root package.json (npm workspaces: apps/*, packages/*), a packages/shared package for types shared between front and back, apps/web (Vite + React 19 + React Router 7, tsconfig, a hand-styled styles.css with an accent colour, one .tsx file per page complete with nav), apps/api (Fastify 5 + CORS, one route file per API route, /api/health), and a real README.md documenting how to run it. Every page and route’s copy/sample-data comes from one cheap-tier structured call (planWithModel()) — coverage is guaranteed by merging the model’s output back onto a deterministic placeholder plan for anything it dropped, so every requested page and route always exists even if the model forgets one.

The build step

If build is true (the default), it runs npm install then npm run build for the web workspace only, best-effort, within buildTimeoutMs. Secrets are stripped from the child process environment first (OPENROUTER, SECRET, TOKEN, PASSWORD env keys deleted) before the install/build runs. On success, previewPath points at apps/web/dist/index.html — this is what assembleOutputs() later detects as a react-app/fullstack-app output with a live preview. If the build fails or times out, the skill still returns success with built: false — the source is still there and downloadable even without a working preview.

Example

Terminal window
curl -s -X POST http://localhost:4000/api/studio/skills/invoke \
-H 'content-type: application/json' -b cookies.txt \
-d '{"name":"code.scaffold_react_node","input":{"name":"Ledgerly","description":"A shared expense tracker for a household.","pages":["Home","History"],"apiRoutes":["GET /api/expenses","POST /api/expenses"],"build":false}}'