The reference map¶
The guide teaches you the model; the exact contracts live in spec. This page is the bridge between them. When you need the precise answer — the exact shape of an effect map (the data an event handler returns to describe what should change), the full failure list, a function's complete signature — you've left the guide. Rather than copy all of that here, this page tells you where each kind of precise answer lives. It's a map of the reference surfaces, not a copy of them.
Three layers, four entry points¶
The docs come in three layers, and it helps to know which one you're standing in. This guide (tutorial, how-to, explanation) teaches you the model. The API reference is the signature lookup, organised by domain — go there once you know the concept and just need the call shape. The spec is the normative source: exhaustive, written for AI and implementors, and the thing every other layer is downstream of. So when two sources seem to disagree, the spec wins.
Four spec documents are entry points, not contracts. They're worth knowing by name:
- Ownership — the "where does X live?" matrix. Every contract surface maps to exactly one owning spec document, so when you don't know which document answers your question, start here.
- Conventions — the reserved
:rf/*namespace scheme, reserved fx-ids, reserved app-db keys (app-db is your app's single state map), and packaging conventions. - Principles — the nine practical principles the design serves, so you can see the reasoning behind a rule, not just the rule.
- The spec index — the full catalogue. It includes the
Pattern-*documents, which name canonical shapes (app boot, websockets, stale-reply detection, the nine render states, and more) — handy when your problem turns out to be a recurring one.
The API surface, by domain¶
Every public surface gets one row below. The API page gives signatures with intuition notes; the owning spec gives the normative contract when intuition isn't enough.
| Domain | What it covers | API page | Owning spec |
|---|---|---|---|
| Core | reg-event, reg-sub, dispatch, subscribe, frames — the loop's registration and verb surface |
01 — Core | 001-Registration, 002-Frames |
| Views | reg-view and the substrate-agnostic pure-view contract |
02 — Views | 004-Views |
| Effects and interceptors | The closed :db + :fx effect map, reg-fx / reg-cofx, interceptors, fx-overrides |
03 — Effects | 002-Frames |
| State machines | reg-machine and the transition-table grammar — hierarchy, :after, :spawn, parallel regions |
04 — Machines | 005-StateMachines |
| Flows | reg-flow — derived values materialised into app-db so handlers can read them |
05 — Flows | 013-Flows |
| Routing | reg-route, navigation events, the :route sub, blocking and not-found |
06 — Routing | 012-Routing |
| HTTP | :rf.http/managed — decode pipeline, retry, abort, the closed failure taxonomy |
07 — HTTP | 014-HTTPRequests |
| Schemas and classification | :schema metadata, reg-app-schema, sensitive / large marks |
08 — Schemas | 010-Schemas, 015-Data-Classification |
| SSR | render-to-string, hydration, streaming boundaries |
09 — SSR | 011-SSR |
| Testing | Fixtures, dispatch-sequence, compute-sub, the helper namespaces below |
10 — Testing | 008-Testing |
| Instrumentation | The dev trace bus, the always-on event / error emit substrates, the epoch buffer | 11 — Instrumentation | 009-Instrumentation, Tool-Pair |
| Registrar queries | registrations, handler-meta — the read-side query API tools build on |
12 — Registrar | 001-Registration |
| Lifecycle | init! adapter selection at boot, adapter inspection, teardown |
13 — Lifecycle | 006-ReactiveSubstrate |
| Adapters | The Reagent / UIx / Helix / reagent-slim substrate surfaces, use-subscribe, frame-provider |
14 — Adapters | 006-ReactiveSubstrate |
| Removed / not shipped | What's gone since v1 and what replaced it | 15 — Removed | Migration rules |
| Resources | reg-resource / reg-mutation — declarative server state and the invalidate-then-refetch loop |
16 — Resources | 016-Resources |
Want the same surface on one page — every signature, status, and tier in one Ctrl-F target? That's spec/API.md.
The test-helper namespaces¶
There are three test namespaces, split by what each one asserts against — the split tells you which to require. The first two ship in the core artefact; the third ships with HTTP.
| Namespace | Asserts against | Representative helpers |
|---|---|---|
re-frame.test-support |
Runtime state — frames, the registrar, app-db, the dispatch drain | with-fresh-registrar, make-reset-runtime-fixture, dispatch-sequence, assert-path-equals / assert-db-equals, poll-until |
re-frame.test-helpers |
The view tree — hiccup data, :data-testid selectors, attached handlers |
the find-by-testid family, text-content, extract-handler / invoke-handler, the with-app-fixture / expect-text / wait-until trio, testid |
re-frame.http-test-support |
The HTTP boundary | canned-reply stub fxs, with-managed-request-stubs |
The full inventory is in 10 — Testing, and the working recipes are Test an event handler and Test a full cascade.
Images and frames: the composition model¶
The public model is image → frame → event stream. An image is a value naming a set of registrations (events, subs, fx, …) plus their capability requirements — built with rf/image, either by selecting registrations from loaded namespaces (:include-ns) or by listing them inline. A frame is the live isolated execution context: it owns the app state, the subscription cache, the trace surface, the adapter binding, a capability map, and one resolved image generation. You build a frame from images with rf/make-frame:
(rf/make-frame {:id :app/main
:images [app-image]
:adapter :reagent
:capabilities {:rf.capability/http http-client}})
A frame is the natural unit for hermetic tests and multi-program inspection: each frame runs its own sealed registration set, so two frames can hold different handlers for the same id without collision. A single-app process never composes images by hand — it just reg-*s into the global registrar and the runtime assembles the standard image for it.
The internal installation substrate
Underneath, the runtime still seats frames through an internal installation container (the EP-0013 "realm" — the registrar, adapter selection, and capability map). That substrate is internal implementation structure, not a public surface: there is no public realm constructor or realm-scoped dispatch option in the image → frame → event stream model. The public address is always the frame id. The internal-substrate model is owned by Runtime-Subsystems; the public image/frame model is owned by EP-0023. The contract rows for rf/make-frame / rf/image are in spec/API.md §Registration.
The worked examples¶
The examples catalogue is the runnable canon. When you're starting something new, the fastest path is usually to fork the one closest to what you're building. The tree:
- Pedagogical sketches —
counter,login,routing,ssr,managed_http_counter,state_machine_walkthrough,boot,flows,websocket,long_running_work. Each isolates one surface, composed end-to-end. - Benchmarks —
todomvc, theseven_guiscluster,nine_states. Same primitives, fuller compositions. - Server state —
resources,resources_ssr,ssr_streaming. - The RealWorld pair —
realworldon:rf.http/managed, andrealworld_resourceson resources + mutations. This is the "what does a real one look like?" answer, and the app this guide's tutorial builds. - Other substrates —
uix/andhelix/each carry counter + login (the dataflow is identical; only the view layer differs), plus one design-led example each.reagent-slim/carries the slim adapter's counter fixture.
Tools, and where their docs live¶
- Xray — the in-app inspection panel: events, sub runs, app-db diffs, machine transitions, time-travel, per frame. Ten doc pages plus an API reference. The guide's working introduction is Debug with Xray.
- Story — the frame-aware component playground. It's Storybook-flavoured, built on re-frame2's own primitives. Nine doc pages plus an API reference.
- The pair MCP —
tools/re-frame2-pair-mcplets an AI agent attach to your running app: inspect a frame, dispatch, hot-swap handlers, time-travel. You drive it through the skill below.
The skills are Claude Code skills for putting an agent to work on a re-frame2 app: re-frame2-setup scaffolds a new app, re-frame2 is the authoring skill, re-frame-migration drives a v1 port, re-frame2-pair pairs against a running app, and re-frame2-xray drives the inspection surface.
Coming from re-frame v1¶
From re-frame v1 is the narrative delta — what carries over (almost everything), what changed and why. The mechanical rule set is the migration reference, and for any real port the re-frame-migration skill is the recommended driver. When a name you remember has simply vanished, 15 — Removed is where to look.
You can now:
- find the owning spec document for any contract surface, starting from Ownership when unsure
- look up any public function by domain in the API reference
- name which test-helper namespace a given test should require
- pick the worked example closest to what you're building, and know where Xray, Story, and the skills are documented