Readable state over time, authored in Markdown.
Throughline compiles small, explanatory state traces into deterministic, versioned snapshots. Its optional React player makes each change visible as a step-by-step SVG scene—with keyboard controls, accessible descriptions, responsive layouts and opt-in sound.
Use it to explain what changes during an algorithm, a data-structure operation, a recursive call or a system workflow. Throughline does not execute arbitrary code or require an account, server, network connection or application-specific runtime.
- Author in Markdown: write a
thlcode fence with explicit, named steps. - Deterministic snapshots: compile once, then seek through immutable frames without re-running the authored program.
- Five supported domains: hand-authored
flow, referencebindings,binaryaddition,matrixmultiplication and recursivecallstack. - Remark validation and MDX output are optional: validate fenced traces without changing Markdown, or emit registered React components from MDX.
- React is optional: use the pure compiler from Node or other ESM environments without loading React or browser globals.
- Accessible playback: keyboard navigation, step captions, a state inspector, reduced-motion support and explicit CSS/theme controls.
- Bounded by design: source, state, event and expansion limits provide predictable rejection rather than uncontrolled trace growth.
- Complex reference traces: inspect keyed React reconciliation and a distributed checkout with a lost acknowledgement, retry and recovery.
Install the package from npm:
npm install @0xbuff/throughlineFor the optional React player, use React 19 and React DOM 19 in the consuming application:
npm install react@^19 react-dom@^19The package targets Node.js 24 or later, uses ESM and ships TypeScript declarations. React is not required for the root compiler import.
import { compile } from "@0xbuff/throughline";
const source = [
"```thl flow",
'node counter "Counter" = 0',
'step "Increment"',
" set counter = 1",
" focus counter",
' note "Counter now holds one."',
"```",
].join("\n");
const trace = compile(source);
// Frame 0 contains the initial state; later frames capture authored steps.
console.log(trace.version); // 1
console.log(trace.frames.length); // 2A thl flow block declares entities and relationships first, followed by
named steps using operations such as set, focus, note, send,
show and hide. Markdown fences are optional when calling compile
directly, but each source must identify its thl domain.
import { compile } from "@0xbuff/throughline";
import { EXAMPLES } from "@0xbuff/throughline/examples";
import { ThroughlinePlayer } from "@0xbuff/throughline/react";
import "@0xbuff/throughline/styles/throughline.css";
const trace = compile(EXAMPLES[0].source);
export function TraceDemo() {
return <ThroughlinePlayer trace={trace} title="React Reconciliation" theme="auto" />;
}The React player and stylesheet are optional. Read the player and Markdown guide for theming, accessible controls, narration, hierarchy, scenarios and MDX integration.
The Vite playground renders the current checkout's source, not necessarily the version currently available from npm. With Node.js 24+ and pnpm 11.2.2:
pnpm install --frozen-lockfile
pnpm devOpen http://localhost:5173 to step through examples, compare scenarios and inspect responsive layouts. The playground is excluded from the published npm package.
- Parse:
compilereads onethl <domain>block, preserving useful source-line information for diagnostics. - Build:
flowis parsed into an authored program; computed domains construct the same program model from bounded input parameters. - Validate and compile: the engine rejects invalid references, JSON values, conflicting writes and excessive work, then produces an initial frame plus a snapshot for each step.
- Present (optional): the React player uses the compiled frames to render a responsive scene, controls, captions and an inspectable state. Seeking a frame does not execute the source a second time.
Trace schema version 1 is independent of the npm package version.
Source length is capped at 262,144 UTF-16 code units; the authored
program is limited to 200 entities, 1,000 relations, 2,000 steps and
10,000 events, plus work/expansion budgets. These limits are for
deterministic work, not a guarantee of exact heap or CPU usage.
- Documentation website
- User guide: player, themes, audio, navigation and Markdown
- Grammar reference and supported domains
- Framework integration guide
- Architecture and trace model
- Complete documentation index
- Changelog, v0.1.0 release notes and upgrade guide
To build and verify a checkout, use the development and verification commands.
Read contributing guidelines before opening a PR. Use GitHub issues for reproducible bugs and feature proposals; see support guidance for support and SECURITY.md for confidential vulnerability reports. Participation is governed by the code of conduct.
Licensed under Apache-2.0. Copyright 2026 0xBUFF; see COPYRIGHT.md. The license covers software rights under its terms, not trademark use.