Version 0.9.5 released Check out what's new

Write Markdown. Get structure.

A content framework built on Markdoc. Extend Markdown with 100+ semantic runes — tags that transform standard Markdown into structured, SEO-rich, machine-readable content.

npm create refrakt
{% hero align="left" spacing="tight" layout="split" collapse="lg" %}
Version 0.9.2 released [Check out what's new](/releases)

# Write Markdown. Get structure.

A content framework built on [Markdoc](https://markdoc.dev). Extend Markdown with 100+ semantic runes — tags that transform standard Markdown into structured, SEO-rich, machine-readable content.

```shell
npm create refrakt
```

- [Get Started](/docs/getting-started)
{% /hero %}

The framework

Why refrakt.md?

Markdown is powerful but limited. Runes extend it with semantic structure — without inventing a new syntax or locking you into a framework.

Built on Markdoc
Not another Markdown dialect. refrakt.md extends Markdoc with semantic runes that add meaning to the Markdown you already write. Everything Markdoc does, you keep.
Runes, not components
Runes reinterpret the Markdown inside them. A heading inside {% nav %} becomes a group title. A list inside {% cta %} becomes action buttons. You write Markdown — the rune decides what it means.
SEO from the start
Every rune can emit Schema.org JSON-LD and Open Graph metadata automatically. Recipes get Recipe schema, events get Event schema, FAQs get FAQ schema — no manual wiring.
AI-powered authoring
Generate full pages with refrakt write. The CLI knows every rune and produces valid Markdown with proper rune structure. Supports Claude and local models via Ollama.
Layout inheritance
Define regions in _layout.md files that cascade down directory trees. Headers, navigation, and sidebars compose automatically — no config files needed.
Portable content
Runes transform at the Markdoc level, producing a generic tag tree. Your content stays decoupled from presentation — adapters for SvelteKit, Astro, Next.js, Nuxt, Eleventy, and plain HTML.

Composable by design

Runes that work together

The sandbox rune renders code fences as live previews in isolated iframes. Drop two of them inside a juxtapose and you get an interactive light-vs-dark comparison — no custom code. Each rune handles its own job while combining into something greater than the parts.

Built-in SEO

Structured data from plain Markdown

Every rune can emit Schema.org JSON-LD automatically. Write a recipe in Markdown — headings, lists, paragraphs — and the framework extracts Recipe schema, ingredient lists, and step instructions without any manual wiring.

{% recipe prepTime="PT5M" servings=1 difficulty="easy" layout="split-reverse" collapse="md" %}
A cocktail classic

## Tequila Sunrise

A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.

- 60ml tequila
- 120ml fresh orange juice
- 15ml grenadine
- Orange slice and cherry for garnish

1. Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.
2. Slowly pour grenadine over the back of a spoon so it sinks to the bottom.
3. Let the layers settle, then garnish with an orange slice and a cherry.

---

![A tequila sunrise cocktail](https://assets.refrakt.md/tequila-sunrise.png)
{% /recipe %}
<article data-field="content-section" data-rune="recipe" typeof="Recipe">
  <meta content="PT5M" data-field="prep-time" property="prepTime">
  <meta content="" data-field="cook-time" property="cookTime">
  <meta content="1" data-field="servings" property="recipeYield">
  <meta content="easy" data-field="difficulty">
  <meta content="split-reverse" data-field="layout">
  <meta content="1 1" data-field="ratio">
  <meta content="top" data-field="valign">
  <meta content="md" data-field="collapse">
  <div data-name="media">
    <img src="https://assets.refrakt.md/tequila-sunrise.png" alt="A tequila sunrise cocktail" property="image">
  </div>
  <div data-name="content">
    <header>
      <p data-name="eyebrow">A cocktail classic</p>
      <h2 id="tequila-sunrise" data-name="headline" property="name">Tequila Sunrise</h2>
      <p data-name="blurb" property="description">A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.</p>
    </header>
    <ul data-name="ingredients">
      <li data-name="ingredient" property="recipeIngredient">60ml tequila</li>
      <li data-name="ingredient" property="recipeIngredient">120ml fresh orange juice</li>
      <li data-name="ingredient" property="recipeIngredient">15ml grenadine</li>
      <li data-name="ingredient" property="recipeIngredient">Orange slice and cherry for garnish</li>
    </ul>
    <ol data-name="steps">
      <li data-name="step" typeof="HowToStep" property="recipeInstructions">
        <p property="text">Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.</p>
      </li>
      <li data-name="step" typeof="HowToStep" property="recipeInstructions">
        <p property="text">Slowly pour grenadine over the back of a spoon so it sinks to the bottom.</p>
      </li>
      <li data-name="step" typeof="HowToStep" property="recipeInstructions">
        <p property="text">Let the layers settle, then garnish with an orange slice and a cherry.</p>
      </li>
    </ol>
  </div>
</article>
Prep:5mServes:1easy
A tequila sunrise cocktail

A cocktail classic

Tequila Sunrise

A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.

  • 60ml tequila
  • 120ml fresh orange juice
  • 15ml grenadine
  • Orange slice and cherry for garnish
  1. Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.

  2. Slowly pour grenadine over the back of a spoon so it sinks to the bottom.

  3. Let the layers settle, then garnish with an orange slice and a cherry.

<article data-field="content-section" typeof="Recipe" class="rf-recipe rf-recipe--split-reverse rf-recipe--easy" data-layout="split-reverse" data-prep-time="PT5M" data-servings="1" data-difficulty="easy" data-ratio="1 1" data-valign="top" data-gap="default" data-collapse="md" data-rune="recipe" data-density="full" data-media-position="top" style="--split-ratio: 1fr 1fr; --split-valign: start; --split-gap: var(--rf-spacing-md)">
  <div data-name="meta" class="rf-recipe__meta" data-section="header">
    <span data-name="meta-item" data-meta-type="temporal" data-meta-rank="primary" class="rf-recipe__meta-item">
      <span data-meta-label="">Prep:</span>
      <span data-meta-value="">5m</span>
    </span>
    <span data-name="meta-item" data-meta-type="quantity" data-meta-rank="primary" class="rf-recipe__meta-item">
      <span data-meta-label="">Serves:</span>
      <span data-meta-value="">1</span>
    </span>
    <span data-name="badge" data-meta-type="category" data-meta-rank="primary" data-meta-sentiment="positive" class="rf-recipe__badge">easy</span>
  </div>
  <div data-name="media" class="rf-recipe__media" data-section="media" data-media="cover">
    <img src="https://assets.refrakt.md/tequila-sunrise.png" alt="A tequila sunrise cocktail" property="image" />
  </div>
  <div data-name="content" class="rf-recipe__content">
    <header data-name="preamble" class="rf-recipe__preamble" data-section="preamble">
      <p data-name="eyebrow" class="rf-recipe__eyebrow">A cocktail classic</p>
      <h2 id="tequila-sunrise" data-name="headline" property="name" class="rf-recipe__headline" data-section="title">Tequila Sunrise</h2>
      <p data-name="blurb" property="description" class="rf-recipe__blurb" data-section="description">A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.</p>
    </header>
    <ul data-name="ingredients" class="rf-recipe__ingredients">
      <li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">60ml tequila</li>
      <li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">120ml fresh orange juice</li>
      <li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">15ml grenadine</li>
      <li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">Orange slice and cherry for garnish</li>
    </ul>
    <ol data-name="steps" class="rf-recipe__steps" data-sequence="numbered">
      <li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
        <p property="text">Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.</p>
      </li>
      <li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
        <p property="text">Slowly pour grenadine over the back of a spoon so it sinks to the bottom.</p>
      </li>
      <li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
        <p property="text">Let the layers settle, then garnish with an orange slice and a cherry.</p>
      </li>
    </ol>
  </div>
</article>

9 packages, 100+ runes

A rune for every domain

Core ships with essentials like hint, tabs, and accordion. Community packages add domain-specific runes — install only what you need.

Marketing
hero, cta, feature, pricing, testimonial, bento, steps, comparison
Docs
api, symbol, changelog
Design
swatch, palette, typography, spacing, preview, mockup
Learning
howto, recipe
Storytelling
character, realm, faction, lore, plot, bond, storyboard
Business
cast, organization, timeline
Places
event, map, itinerary
Media
playlist, track, audio
Plan
spec, work, bug, decision, milestone

Once you see content through the refrakt lens, plain Markdown starts feeling like it's leaving so much on the table.

Claude OpusAI, Anthropic

Ready to get started?

Scaffold a project in seconds and start writing content with runes.