Concepts

Core concepts

Morphis has four moving parts. Understand these and every other page in the docs will click into place.

1. Intent

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.

Write intents like a product spec, not a command. "A sortable table of invoices with a red badge for overdue" gives the model far better output than "table".

2. Context data

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.

context-data.json
{
  "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.

  • Size limit: context payloads are capped at 50 KB on the platform API route, and the backend enforces a separate 200 KB ceiling with a 10,000-key cap.
  • Never send PII you wouldn't render. If a value shouldn't appear in the UI, don't send it.

3. The safety pipeline

Every generation flows through four stages. This is the heart of Morphis and the reason untrusted model output can safely live inside your app:

pipeline
  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.

4. Metering and tenancy

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.

  • API keys are hashed (SHA-256) at rest — the plaintext is shown once at creation.
  • Each key belongs to a tenant. Quota is per-tenant, shared across its keys.
  • Responses carry metadata.tokensUsed for LLM calls and source: "llm" | "fallback" so you can tell which engine produced the result.
Next: see the JavaScript SDK reference, or go straight to the API reference.