Changelog
0.43.0 Section is the composition base
A composition that wants a titled region with media places {% section %}, not {% card %}. section gains a body role, a header grammar that no longer reads prose as a header, the media split, cover and a media kind. The composed storytelling runes move onto it, and two new primitives arrive: {% actions %} for rows of buttons and a block-level {% link %}. card renders exactly as it does today (ADR-041, ADR-046, SPEC-160).
0.42.0 What a composition can express
Since v0.41.0, anyone can write a composed rune. This milestone widens what a definition can say. Templates may be indented, and refrakt format indents nested runes for you. Content may be split on --- into named zones, a sections model may treat content with no headings as one section, and each can walk the items of a plain list. An itemModel declared in YAML now extracts its fields instead of leaving every one empty (SPEC-169, SPEC-170).
0.41.3 A fresh scaffold works
A project made with create-refrakt builds with no errors, and the HTML starter runs the plugins it is configured with. Building plan content no longer slows down with the length of the repository's git history, and a sandbox receives the design tokens the pipeline injects.
0.41.2 Changelog titles and the iOS drawer fix
A changelog release can now have a title, written after the version, and the site's changelog shows one for every release. On iOS Safari, the sticky site header no longer trails behind page scrolling after a drawer has been opened (BUG-044).
0.41.1 Readable release notes
The changelog on the site is now a list of short summaries, one per release, saying what each release is for. Every release has its own page with the specs and bugs behind it as drawers and the full list of changes (SPEC-176). This release also fixes plan validate --against, which missed an ID collision with anything main created after a branch split off (BUG-040), and plan create milestone, which named the file after the title instead of the version (BUG-041).
0.41.0 Composed runes you can ship
v0.40.0 let a rune be defined as a template that places existing runes, but only from inside this repository. Now you can write your own: put a <rune>.md in your project's runes/ directory, or ship a directory of them from a plugin by declaring runeDir. The composed runes guide covers the file format, where definitions go, and every error a definition can produce.
Action needed: content-unmatched is now an error. Content inside a rune that no part of its content model reads used to be dropped without a word. It now fails refrakt validate and the build, naming the rune, the node and its line. The content never rendered, so the fix belongs in the rune: give it a field that takes the content, or set rawBody: true if its transform reads the raw source. To unblock a build meanwhile, add "content-unmatched" to validation.disableIds.
Plugin authors: a by schema table now needs a row for every value in its attribute's matches, or the rune fails to build.
0.40.0 The first composed rune
A rune can now be defined as a Markdoc template that places existing runes, instead of a transform written in code. Composition is proved on two storytelling runes, bond and character, beside the plugin's own versions, so nothing you render changes yet. Separately, sandbox's context attribute now takes effect: context="dark" gets the dark token set instead of the default one.
Action needed for theme authors: a theme can no longer override a rune's sequence, a meta field's metaType, or a layout wrapper attribute that a rune's identity emits. Each is part of what the rune means, not how it looks. Such an override is now dropped and reported; the presentation keys beside it still apply.
0.39.0 Declarations, part two
More of what runes did in code is now declared as data: a rune can declare what it registers in the cross-page registry and which output slots it fills, and the storytelling, design and plan runes have moved over with unchanged output. {% figure %} now keeps everything you put in it and captions it, instead of silently dropping anything that is not an image.
Action needed: a standalone {% snippet %} no longer renders inside <figure class="rf-snippet">. It is now the <pre data-source> a fenced code block produces, so CSS or tooling that selects .rf-snippet or [data-source-path] must move to pre[data-source]. And parentUrl is now spelled exactly like the parent page's url: a query on parentUrl:/docs/ must use parentUrl:/docs.
0.38.0 Rune transform consolidation
Rune transforms lose code that did nothing: metas emitted only to be filtered back out, an unused schema.org channel, and guards that guarded nothing, with rendered output unchanged. Two declarations now reach the author: a mixed list-and-tag field no longer drops the tags written in it, and refrakt reference shows each field's authoring grammar.
0.37.0 Documentation drift
snippet, file-ref and expand can name the code they embed, by symbol or by match, instead of counting lines that move whenever the file is edited, and refrakt migrate snippets --fix converts existing line ranges. A reviewed= marker records that a person read an embedded slice, and refrakt snippet review --check reports when it changes. refrakt stale ranks documentation by how far the code it describes has moved since the page last changed.
0.36.0 Validation reach
The findings v0.34.0 started producing now reach you: the dev server prints pipeline diagnostics on every content reload, refrakt validate checks your own project's config and content, and the MCP server can run the same check for an agent.
Action needed: refrakt validate used to check refrakt's own built-in config, so it always passed. It now validates your project and exits non-zero when a finding is at error severity. A CI step that runs it may start failing on problems that were always there.
0.35.0 Declarative schema.org mapping
Thirty runes publish structured data. Every one of them writes it by hand, inside its transform, in a channel no tool can read and no reviewer looks at. This milestone turns that channel into data keyed by the rune's own names — the same shape BEM, modifiers and editHints already use — and builds the review surface it has never had.
0.34.0 Content validation
Every rune schema declares required attributes, typed attributes and matches enums. Markdoc can check all of them, and has been able to the entire time. Nothing in the build ever asked it to. This milestone connects the validator that exists to the content it was written for.
0.33.0 Generated reference docs
Reference documentation stops being hand-copied. Every page in the docs that claims to enumerate a complete set — configuration fields, frontmatter fields, a rune's attributes — renders from the source that already knows the answer, guarded by a test that fails when the two diverge.
0.32.0 Narrowed rune schemas
The second half of SPEC-125: a rune's Markdoc schema offers only the universal attributes that can affect it, so refrakt reference, editor completion and Markdoc validation stop over-promising — without any of them loading theme config.
0.31.0 Section-role correctness
reading and dropcap now work on runes where they were silently ignored, most visibly card, because eleven runes now declare which of their parts is the body or the header. No build breaks, but those runes gain data-section and can render differently. Which universal attributes apply to a rune is now part of the rune itself, so a theme cannot change it.
0.30.1 Transform engine facet decomposition
House-cleaning on the most central package in the project. transformRune in packages/transform/src/engine.ts resolves every universal rune axis — tint, density, width, spacing, reading, elevation, prominence, motion, background, frame, substrate, cover — in one ~800-line function whose steps are numbered 1, 1b, 1c … 1h, 2 … 9. This milestone replaces that section with a facet registry (SPEC-124): one module per axis, dependencies declared rather than implied by statement order, and a driver that merges their contributions.
0.30.0 Plan lifecycle validation & render-stack removal
Two threads of plan-tooling hardening that finish work the previous milestones deliberately left open. First, teach plan validate to catch lifecycle drift — statuses that contradict the terminal evidence around them (SPEC-119), the symmetric counterpart to the one-directional lifecycle checks already in place. Second, remove the bespoke plan build / plan serve render stack (SPEC-120) that v0.16.0 deprecated but kept alive — with the SPEC-071 plan-site transition shipped, a plan site is now an ordinary refrakt site, so the parallel SSG can go.
0.29.0 Multi-language support (i18n foundation)
Makes Refrakt's framework-generated text — labels, navigation chrome, accessibility strings, structural headings, and client-side behavior strings — localizable, so a site built for a non-English locale no longer shows English UI chrome around translated content. This milestone delivers the string-resolution foundation of SPEC-035. Serving the same site in multiple languages (route trees, switcher, auto-detect) remains a deliberate Non-Goal that this foundation is explicitly constrained to allow later without breaking changes.
0.28.0 Plan model hardening
Tighten the plan runes' data model along three axes: status vocabulary, spec/PR traceability, and the dependency graph — then sweep the existing content to match.
0.27.0 External data & hosted content
Two threads that together let the pipeline ingest real data from outside the content tree and run without a local filesystem. The first feeds charts and sortable tables from actual data files; the second consolidates the remaining ad-hoc fs seams into one injectable interface so a hosted renderer (the GitHub-app product) can build a tenant's repo straight from the API.
0.26.0 Editorial reading & shared layout modes
Continues the SPEC-094 theme-platform arc by settling the two capability gaps it deferred: the reading register for body text (the last reserved §8 candidate) and the promotion of carousel from a gallery-coupled behavior to a canonical layout mode any rune can opt into. Where v0.23.0 governed a rune's container (elevation/prominence/width), this milestone reaches inside it — how the running text reads, and how homogeneous items lay out.
0.25.1
0.25.0 Distribution & onboarding
With the theme platform matured across v0.22.0 (type tokens), v0.23.0 (surface axes + skeleton/skin) and v0.24.0 (live backdrops + motion), the next move is to make that platform distributable and cut the largest activation cost in the toolchain: the blank page. Three recent specs interlock to take an author from zero to a designed, purpose-built site — starting templates, robust install from anywhere, and presets shippable independent of a theme.
0.24.6
0.24.5
0.24.4
0.24.3
0.24.2
0.24.1
0.24.0 Live backdrops & scroll-reveal motion
bg can host a live sandbox as a full-bleed animated backdrop behind a surface's content. A new reveal attribute, with stagger, animates runes into view as they scroll in, driven by theme tokens and skipped when motion is reduced or scripts are off.
0.23.0 Surface axes & the skeleton/skin extraction
The second slice of the SPEC-094 theme-platform epic. Where v0.22.0 tokenized type and built the gallery safety net, v0.23.0 attacks the differentiation surface: it extracts skeleton from skin and replaces the last cross-rune rune-name lists with engine-emitted, theme-overridable config.
0.22.0 Theme platform foundations
The first slice of the SPEC-094 theme-platform epic: make the theme system ready to support themes beyond Lumina (magazine / editorial / business) — without yet building one. Two independent threads — tokenize + generate and gallery + visual-regression harness — plus the spike that sizes the v0.23.0 skeleton/skin extraction.
0.21.0 Registry-driven composition and sandbox integration
A minor release turning the entity registry into something you can author over and visualize — making content queryable by frontmatter, and letting sandboxes be fed registry data to drive arbitrary client-side renderings (3D sitemaps, relationship graphs). The thread that runs through it: the registry's render targets grow from HTML and SVG to bring-your-own-renderer.
0.20.2 HTML scaffold client runtime
A focused patch closing the @refrakt-md/html scaffold's interactivity gap: the adapter ships the client runtime (@refrakt-md/html/client + @refrakt-md/behaviors) but template-html's build never bundles or references it, so a scaffolded static site has inert tabs, accordion, search, and theme-toggle. This milestone makes a scaffolded html site interactive out of the box.
0.20.1 Surface model: docs & showcase
A documentation-and-showcase patch on top of v0.20.0. The surface model shipped with per-rune reference docs; this milestone makes it land — a cohesive showcase of the vocabulary as a system — and consolidates the composition docs. No new runtime features.
0.20.0 Surface model: chrome, fills, cover layout & engine variants
Completes the surface model — every rune surface gets a consistent chrome, fill, and layout vocabulary — and lands the engine primitive (config variants) that the cover layout depends on.
0.19.0 Polish, composability & rollups
Where v0.18.0 hardened the rune output contract, v0.19.0 builds on that stable base along several threads: visual polish of the Lumina theme, making rune composability a supported and validated surface (SPEC-084), turning bento into a proper composition substrate (SPEC-085), and improving the cross-page aggregation runes that the plan plugin leans on.
0.18.0 Contract hardening
Follows v0.17.0's declarative metadata-and-layout model. The release hardens the rune output contract before third-party themes build against it, and lands the one breaking change held back from v0.17.0.
0.17.0 Declarative metadata & layout
The v0.17.0 milestone follows v0.16.0's registry-driven sites with a fully declarative model for how metadata-bearing and media-bearing runes are assembled — replacing per-rune imperative structure code with a small, orthogonal config vocabulary (metaFields + blocks + layout) and giving every rune a consistent, theme-overridable metadata treatment. It also lands the file-ref rune and the shared preview drawer.
0.16.1
0.16.0 Registry-driven sites
v0.16.0 turns the entity registry into pages and listings declaratively, delivers the three sibling registry-query runes (collection / relationships / aggregate — items / edges / numbers), and proves the system by scaffolding a real plan site from refrakt's own plan/ content. Builds directly on v0.15.0's embedding primitives (ref / expand).
0.15.0 Composable embedding
The v0.15.0 milestone delivers the cluster of runes and infrastructure that makes refrakt's "embed anything inline" story real: a body-only drawer rune with xref-as-trigger (SPEC-060), an expand rune that inlines registered entities (SPEC-066), a snippet rune that embeds project files as syntax-highlighted code (SPEC-062), and the supporting plumbing that ties them together: $page.*/$file.* page variables (SPEC-061), generic file roots for namespaced file resolution (SPEC-063), unconditional plan-entity registration (SPEC-064), and configurable xref resolution with patterns and decoupled entity/URL lookup (SPEC-065).
0.14.4 Framework adapter parity with the SvelteKit reference
The v0.14.4 milestone implements SPEC-058 — closes the parity gap the v0.14.x patch line opened between @refrakt-md/sveltekit (the adapter the refrakt documentation site itself ships on) and the four other framework adapters (@refrakt-md/astro, @refrakt-md/nuxt, @refrakt-md/next, @refrakt-md/eleventy) plus the framework-agnostic @refrakt-md/html renderer.
0.14.3 Navigation enrichment: slug resolution and richer dropdowns
The v0.14.3 milestone delivers two coordinated navigation specs: SPEC-055 fixes nav slug ambiguity and the multiple-items-active-at-once symptom by moving slug resolution to build time and introducing multi-segment slugs as the first-class disambiguator; SPEC-054 extends the existing nav layouts so authors can compose Linear- / Vercel- / Stripe-style header dropdowns from the primitives they already know — layout="menubar" accepts arbitrary block content inside ## groups with a position-based intro / footer slot rule, layout="columns" gains a ----between-sections column-flow rule plus a headingless mode, and a new layout="strip" lands for compact secondary link rows. Plus a new core {% badge %} inline rune and a generalisation of auto=true description / icon enrichment to every layout.
0.14.2 Curated syntax preset lineup (Phase 1)
The v0.14.2 milestone implements SPEC-057 — imports six widely-recognised syntax palettes (Dracula, Solarized, Catppuccin, Tokyo Night, One Dark, Gruvbox) as first-party refrakt presets, following the pattern established by Nord in WORK-220.
0.14.1 Syntax token contract extension
The v0.14.1 milestone implements SPEC-056 — widens the SyntaxTokens contract from 7 required + 2 optional roles to 7 required + 9 optional, with fallback chains via CSS var() so simple presets stay simple and richer presets gain the headroom to faithfully carry well-known palettes (Nord, Dracula, Solarized, Catppuccin, Tokyo Night, GitHub, …) without losing the role splits their authors designed in.
0.14.0 Design tokens contract + brand identity
The v0.14.0 milestone establishes refrakt's design tokens contract as a typed, theme-agnostic surface (SPEC-048), refreshes the brand mark with a monochrome prism logo (SPEC-050), aligns tint vocabulary with the rest of the token system (SPEC-053), ships Lumina with a neutral default palette plus two opt-in presets — tideline and niwaki — that demonstrate the preset architecture (SPEC-051), and lets authors lock or unlock tint modes per page or subtree via frontmatter cascade (SPEC-052).
0.12.0 Plugin unification & hardening
Rune packages are now plugins throughout: site.packages[] becomes site.plugins[], and the old field is rewritten automatically while it is deprecated. The config's JSON Schema is published at a versioned URL, and an opt-in security policy lets a hosted product render untrusted content with layered defences.
0.11.3
0.11.2
0.11.1
0.11.0 Unified config & MCP server
refrakt.config.json becomes one root config for plugins, the plan and one or more sites, and every framework adapter can pick its site. The new @refrakt-md/mcp package exposes the refrakt CLI as a Model Context Protocol server, so agents get typed tools instead of parsing command output.
0.10.1
0.10.0
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0 Universal Theming & Package Pipeline
Metadata dimensions, universal theming, rune output standards, the plan package, Markdoc partials, and a Lumina design refresh. Read more in What's New in 0.9.0.
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
Declarative content models, a cross-page pipeline, media runes with streaming, and identity transform improvements. Read more in What's New in 0.8.0.
0.7.2
0.7.1
0.7.0
Eight official rune packages and new tooling for package authors. Read more in What's New in 0.7.0.
0.6.0
A full WYSIWYG editor, framework-neutral web components, a layout transform engine, an AI-powered theme designer, and a Python extraction pipeline. Read more in What's New in 0.6.0.
0.5.1
0.5.0
A theme development toolkit, a behaviors library, six new runes, a VS Code language server, and a major shift toward framework-agnostic rendering. Read more in What's New in 0.5.0.
0.4.0
New packages, seven new runes, theme restructuring, syntax highlighting, and more. Read more in What's New in 0.4.0.