Concepts
Morphis has four moving parts. Understand these and every other page in the docs will click into place.
The intent is a plain-English description of the component you want — for example "show a churn-risk table" or "render an onboarding form for new workspaces". Intents are sent to an LLM that produces structured HTML+CSS. You don't write markup, prompts, or templates — you describe the outcome.
Context data is a JSON object containing the live values the component should render. Morphis never connects to your database — you pass the exact data you want displayed, per request.
{
"mrr": 5400,
"churn": 2.4,
"activeUsers": 128,
"plan": "Pro"
}The generation engine is instructed to place these values into the produced markup. Keep it small and focused: a well-chosen 10-key object beats a megabyte dump, both for output quality and for cost.
Every generation flows through four stages. This is the heart of Morphis and the reason untrusted model output can safely live inside your app:
intent + contextData
│
▼
┌─────────────┐ LLM proposes { html, css } JSON
│ LLM call │
└─────────────┘
│
▼
┌─────────────┐ bleach + BeautifulSoup strip scripts, event handlers,
│ Sanitizer │ javascript: URLs, hostile CSS; comments removed
└─────────────┘
│
▼
┌─────────────┐ styles prefixed under .morphis-root so they cannot
│ Scoping │ leak into your page
└─────────────┘
│
▼
┌─────────────┐ rendered in <iframe sandbox="allow-scripts"> —
│ Sandbox │ zero access to your DOM, cookies, or storage
└─────────────┘If the sanitizer strips everything and the result is empty, the API returns a 500-style error rather than serve unsafe output. See the Security page for the full threat model.
Every request is authenticated by an API key, counted against your tenant's monthly quota, and recorded as a generation event. The dashboard shows live usage; limits are enforced at the API layer.
metadata.tokensUsed for LLM calls and source: "llm" | "fallback" so you can tell which engine produced the result.