Plan
ID:SPEC-007Status:draft

Local Runes — Declarative Rune Extension (v1)

Context

Projects need custom interactive components in content — a playground, a pricing calculator, a product demo. Rather than a {% component %} escape hatch that breaks out of the rune system, local runes extend it. To the content author, a local rune looks identical to a built-in rune. The only difference is where it's defined.

This spec covers v1 runtime support: config declaration, schema generation, content parsing, and component rendering. VS Code language server support is a fast-follow.

v1 Config Surface

Local runes are declared in refrakt.config.json:

{
  "contentDir": "./content",
  "theme": "@refrakt-md/lumina",
  "target": "svelte",
  "runes": {
    "playground": {
      "component": "./src/components/Playground.svelte",
      "description": "Interactive code playground with live preview",
      "attributes": {
        "height": { "type": "number", "default": 600 },
        "example": { "type": "string", "default": "default" },
        "editable": { "type": "boolean", "default": true }
      },
      "children": "render"
    },
    "pricing-calculator": {
      "component": "./src/components/PricingCalculator.svelte",
      "description": "Interactive pricing calculator",
      "attributes": {
        "currency": { "type": "string", "default": "USD" },
        "plans": { "type": "string" }
      }
    }
  }
}

Config Fields

FieldTypeRequiredDefaultPurpose
componentstringYesPath to Svelte component (relative to project root)
descriptionstringNo""Human-readable description (used by language server in fast-follow)
attributesRecord<string, AttrDef>No{}Attribute schema for validation
children"none" | "render"No"none"How children are handled

Attribute Definition

interface AttrDef {
  type: "string" | "number" | "boolean";
  default?: string | number | boolean;
  required?: boolean;
}

Children Modes

"none" (default) — Self-closing tag. No closing tag needed. Component receives only declared attributes.

{% pricing-calculator plans="starter,pro" %}