weblocks

Lego bricks for AI-composable web apps

A model composes a SiteManifest from a fixed catalog of typed blocks — its entire API surface. The engine validates it and renders one self-contained static HTML document. No raw HTML from the model, no framework runtime, nothing to trust at render time.

1 · the brief

“a neighbourhood café with a menu, a gallery and opening hours” generateSite(brief, callModel)

2 · the manifest

"meta":   { "title": "Brew & Bloom — Neighbourhood Café" },
"design": { "palette": { "primary": "#3a5a40" } },
"blocks": [
  { "id": "nav", "type": "nav" },
  { "id": "hero", "type": "hero" },
  { "id": "menu", "type": "services-catalogue" },
  { "id": "gallery", "type": "gallery" },
  … 4 more
]

3 · the document

typed JSON in validate render one HTML file out

54typed blocks
160starter templates
0runtime dependencies
1file out — self-contained

Install

npm i @bytesbrains/weblocks
npm ↗ GitHub ↗ Docs ↗

See it rendered

The block wall → All 54 bricks, rendered live, each labelled with the island it hydrates with. Starter templates → 160 complete starter sites across 23 verticals, filterable by trade and page shape.

For AI agents

The consumer of this package is a model, so the contract is fetchable without installing anything. One request each — no npm, no build step.

/llms.txtIndex of everything below, in the convention models look for. /AGENT.mdPrime directives, composing a manifest, editing with ops, guarantees. /catalog.jsonAll 54 block types with full JSON Schema for their config. /catalog.txtThe same vocabulary, one line per block, cheap to put in a prompt. /tools.jsonA ready-to-use compose_site function-calling definition.

Why it is built this way

A closed vocabulary

A block exists only if it is registered. An unknown type is skipped, so a confused model produces a plainer page — never a broken one. illegal states unrepresentable

The renderer is total

Every block fills defaults, escapes its input and never throws. Validity is independent of how good the model's output was. validity ⟂ AI quality

Static first

Pages ship zero JavaScript until a block earns it; interactive blocks hydrate from a small island, and turning the behaviour off ships nothing. 54 blocks, 8 islands

Yours to host

Output is one document with inlined CSS and no external dependencies. Node >=20, MIT, v0.12.0. 0 runtime deps