Server-side
AI Layout Generation
ComposeKitServer generates page layouts from a natural language prompt using BrainPiper's AI. It runs on your server, returns a layout row array, and you pass it to ComposeKitRenderer on the client via the builderState prop.
Important
- Server-side only — never call
ComposeKitServerin browser code - Requires a separate API Key in addition to your Client ID
- The generated layout is a plain
ILayoutarray — no lock-in, you own the data - Works with any server framework: Next.js, Express, Fastify, etc.
Getting an API Key
Generate an API key from BrainPiper Studio → ComposeKit. Store it as an environment variable — never commit it to source control.
Import
server.ts
import { ComposeKitServer } from '@brainpiper/composekit/server';Initialise (once at server startup)
server.ts
// server entry point (e.g. app.ts, server.ts)
import { ComposeKitServer } from '@brainpiper/composekit/server';
ComposeKitServer.init({
clientId: process.env.BRAINPIPER_CLIENT_ID,
apiKey: process.env.BRAINPIPER_API_KEY,
});Generate a layout
server.ts
const result = await ComposeKitServer.createResponse({
prompt: 'Create a user registration form with name, email, and password fields',
});
// result shape:
// {
// success: true,
// data: {
// summary: string, // human-readable description of the generated layout
// builderState: {
// rows: ILayoutRow[],
// dataStores: any[],
// decisionTables: any[],
// workflows: any[],
// }
// }
// }
if (result.success) {
const { summary, builderState } = result.data;
}End-to-end example — Next.js
Create an API route that accepts a prompt, calls BrainPiper's AI, and returns the layout. The client fetches the layout and passes it straight to ComposeKitRenderer.
app/api/generate/route.ts
// app/api/generate/route.ts (Next.js App Router)
import { ComposeKitServer } from '@brainpiper/composekit/server';
ComposeKitServer.init({
clientId: process.env.BRAINPIPER_CLIENT_ID!,
apiKey: process.env.BRAINPIPER_API_KEY!,
});
export async function POST(req: Request) {
const { prompt } = await req.json();
const result = await ComposeKitServer.createResponse({ prompt });
if (!result.success) {
return Response.json({ error: 'Generation failed' }, { status: 500 });
}
return Response.json(result.data);
}MyPage.tsx
// MyPage.tsx
import { useState } from 'react';
import { ComposeKitRenderer } from '@brainpiper/composekit';
export function MyPage() {
const [builderState, setBuilderState] = useState<any>(null);
const [summary, setSummary] = useState<string>('');
const [loading, setLoading] = useState(false);
const generate = async () => {
setLoading(true);
const res = await fetch('/api/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: 'A contact form with name, email, and message' }),
});
const { summary, builderState } = await res.json();
setBuilderState(builderState);
setSummary(summary);
setLoading(false);
};
return (
<div>
<button onClick={generate} disabled={loading}>
{loading ? 'Generating…' : 'Generate layout'}
</button>
{summary && <p>{summary}</p>}
{builderState && (
<ComposeKitRenderer
builderState={builderState}
onUpdate={(dataPath, value) => console.log(dataPath, value)}
/>
)}
</div>
);
}Security checklist
- Store
BRAINPIPER_API_KEYin environment variables, never in client code - Call
ComposeKitServer.init()at server startup, not inside request handlers - Validate and sanitise the
promptcoming from the client before forwarding it - Rate-limit your generation endpoint — AI calls have cost and latency