ComposeKit Docs
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 ComposeKitServer in browser code
  • Requires a separate API Key in addition to your Client ID
  • The generated layout is a plain ILayout array — 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_KEY in environment variables, never in client code
  • Call ComposeKitServer.init() at server startup, not inside request handlers
  • Validate and sanitise the prompt coming from the client before forwarding it
  • Rate-limit your generation endpoint — AI calls have cost and latency