Agent-First Design Tooling

Stop Building
UI Blind.

ReactScope gives AI agents — and the humans reviewing their work — structured, machine-readable visibility into React components. Every render. Every state. Every token. Every reason something re-rendered.

Category Design Tooling
Interface CLI + Static Site
Target AI Agents + Designers
Status In Spec · March 2026

UI is an agent's weakest domain.
Not because of code quality.

Agents write correct React. The problem is feedback. Every tool in the design loop — visual inspection, interaction testing, perf profiling — was built for a human staring at a browser. An agent can't stare at a browser. So it guesses, hopes, and ships layout bugs.

"I can write a DataTable in 4 minutes. I have zero idea if 47 rows re-render every time you sort a column."
Today (Storybook)
Human can visually inspect components
No machine-readable output
Can't batch-render N variants
No render tree or re-render causality
Token compliance is manual audit
Animation frames are invisible
Content stress testing is ad-hoc
No keyboard flow verification
ReactScope
Structured JSON output, not pixels
Render 30 variants, get 1 sprite sheet
Fiber tree with re-render causality chains
Token compliance on every render
Animation extracted as frame sequences
Built-in content stress presets
Keyboard flow as structured data + snapshots
Sub-200ms per variant render

The Render Matrix

One operation at the core of everything. Render N component variants across any combination of axes — props, viewport, theme, content, container — and get back structured data for every cell.

bash — reactscope
$ reactscope render Button \ --matrix '{"variant":["primary","secondary","ghost","danger"],"size":["sm","md","lg"],"disabled":[false,true]}' \ --sprite --json   Component manifest loaded · 47 components Browser process warm · 0ms startup Rendering matrix 4 × 3 × 2 = 24 variants   primary/sm/enabled 4.1ms 100% token compliant primary/md/enabled 3.8ms 100% token compliant primary/lg/enabled 4.2ms 100% token compliant secondary/sm/enabled 3.7ms off-system: #374151 → nearest gray.700 ghost/md/disabled 3.2ms 100% token compliant ... 19 more cells   24 renders in 94ms · avg 3.9ms/cell Sprite sheet → .reactscope/renders/Button.png Token compliance 95.8% (23/24 cells) JSON → .reactscope/renders/Button.json

Output: Sprite Sheet (Button.png) — 24 cells, labeled axes

variant / size
SM
MD
LG
SM dis.
MD dis.
primary
secondary
off-sys
off-sys
ghost
danger
Content stress, responsive sweep, composition contexts — all render matrix axes. One primitive. Infinite configurations.

Every render, explained.

ReactScope instruments the React fiber tree to give you the full picture: what rendered, why, and what could have been skipped. No flame chart — structured data you can query.

App renders: 1 └─ ThemeProvider ctx: ThemeContext └─ UserList renders: 4 ↑ state: data (useQuery) ├─ FilterBar renders: 4 ⚠ parent re-render, props unchanged └─ UserRow ×47 renders: 4 each ⚠ WASTED_RENDER ×47 ├─ Avatar ✓ memo · skipped 3× └─ Badge renders: 4 ⚠ parent re-render
Re-render causality
{
 "component": "UserRow",
 "renderCount": 188,
 "trigger": "parent_rerender",
 "propsChanged": false,
 "stateChanged": false,
 "contextChanged": false,
 "memoized": false,
 "flag": "WASTED_RENDER"
}
Hook Profile · SearchResults
HookTypeFiresCache HitFlag
useState[0]query12
useEffect[1]query dep12KEYSTROKE
useMemo[2]results120%INEFFECTIVE
useCallback[3]onSelect120%INEFFECTIVE
Interaction Profile
$ reactscope instrument profile SearchPage \ --interaction '[{"action":"click","target":"#search"},{"action":"type","text":"hello"},{"action":"wait","condition":"idle"}]'   Interaction completed in 847ms   Total renders 67 Unique components 14 Wasted renders 42 (62.7%) Longest render DataGrid @ 18.4ms JS execution 84ms Layout shifts 2 (CLS 0.20)   WASTED_RENDER detected on UserRow ×47 MEMO_INEFFECTIVE on SearchResults.useMemo[2] — 0% cache hit rate EFFECT_ON_KEYSTROKE on SearchResults.useEffect[1]

Token compliance
on every render.

One token file. Every render audits itself. Off-system values are flagged with nearest-match suggestions. Change a token and instantly preview every component it touches.

reactscope.tokens.json

{
 "color": {
  "primary": {
   "500": { "value": "#3B82F6" },
   "600": { "value": "#2563EB" }
  },
  "semantic": {
   "error": { "value": "{color.red.500}" }
  }
 },
 "spacing": {
  "4": { "value": "16px" },
  "3": { "value": "12px" }
 }
}

Color palette

color.primary.50
color.primary.200
color.primary.400
color.primary.500
color.primary.700
color.neutral.50
color.neutral.200
color.neutral.400
color.neutral.700
color.neutral.900

System Compliance Report

Overall 91.3%
Button.tsx
100%
UserCard.tsx
93%
DataTable.tsx
74%
LegacyCard.tsx
61%
Navigation.tsx
97%
Token Impact Preview
$ reactscope tokens preview color.primary.500 \ --new-value "#2563EB" --sprite   Affects 14 components · 23 element references Button · button.bg (4 variants) Link · a.text Badge · .badge-primary.bg +11 more...   Sprite → .reactscope/preview/primary-500-impact.png

What happens with a
47-character Thai name?

Built-in content stress presets plug directly into the render matrix. One flag catches every edge case: empty, overflow, unicode, RTL, emoji, injection.

Content Stress Test
$ reactscope render ProfileCard \ --stress name --viewports 375,768,1024 --sprite   Expanding preset text.stress (9 variants) × 3 viewports = 27 cells   "" Empty state renders correctly "Jane Smith" "Alexandria Konstan..." TRUNCATED @ 375px "Aaaaaaaaaaaaaaaaaaa" overflows_parent — no word break "田中太郎" "محمد الرشيد" RTL text in LTR container "Jane 🎉 Smith"   2 layout failures · 1 warning Sprite → .reactscope/renders/ProfileCard-stress.png

Sprite Output — ProfileCard × content variants

empty
Jane Smith
Engineer
typical
Alexandria Konstantinidou-P...
Senior Engineer
truncated
Aaaaaaaaaaaaaaaaaaaaaa
Overflow
overflow

See your transitions
frame by frame.

Animations are completely invisible to agents. ReactScope extracts keyframes at configurable intervals and lays them out as a sprite strip — with easing curves rendered side-by-side so you can compare, not guess.

Animation Extraction
$ reactscope render Modal \ --animation enter --frames 6 --easing ease-out,ease-in,cubic-bezier(.2,.8,.3,1)   Detected animation: modal-enter · duration 220ms Extracting 6 frames × 3 easing curves = 18 snapshots 0ms 50ms 90ms 130ms 180ms 220ms Frame strip → .reactscope/animation/Modal-enter.png

Frame strips — Modal enter · 3 easing curves × 6 frames at 0 / 50 / 90 / 130 / 180 / 220ms

ease
out
done
ease
in
done
cubic
.2,.8
.3,1
best
0ms
50ms
90ms
130ms
180ms
220ms
The cubic-bezier row shows an overshoot at 90ms — visible in the frame data, invisible to any other tool. That's the difference.

Components lie
in isolation.

Every component looks perfect in Storybook. Then you put three of them in a flex row with uneven content and something collapses. Composition contexts render the same component into five realistic containers in one call.

Composition Contexts
$ reactscope render UserCard \ --props '{"name":"Jane Smith","role":"Engineer"}' \ --contexts centered,flex-row,sidebar,grid,scroll --sprite   centered no issues flex-row ×3 min-width collapse at sibling 3 sidebar 280px avatar + name overflow container grid 3-col no issues scroll 200px no issues   1 failure · 1 warning Sprite → .reactscope/renders/UserCard-contexts.png

UserCard — 5 composition contexts

centered
Jane Smith
Engineer
pass
flex-row ×3
Jane Smith
Tom
Al...
min-width collapse
sidebar 280px
Jane Smith — Senior
overflow
grid 3-col
Jane
Tom
Alex
pass
scroll 200px
Jane Smith
Tom K.
pass
The sidebar failure would have shipped. Storybook never renders components in 5 containers at once. ReactScope does it in one command.

Review agent changes
like a PR, not a prayer.

Every time an agent modifies components, ReactScope generates a structured change report: before/after sprite sheets, pixel diff, and a machine-readable delta. One document. No guessing what changed.

Change Report
$ reactscope report diff --sprite --out ./reports/latest/   Components changed: 2 Components added: 1 Components removed: 0 Compliance: 87% 93% (+6%) A11y violations: 1 resolved, 0 added   Button.tsx REVIEW background-color/primary: #3B82F6 #2563EB padding/all: 8px 16px 10px 20px token compliance: 87% 100%   Report → ./reports/latest/index.html

Button.tsx — before / after · all variants

Before
After

Structured delta — machine-readable, human-scannable

Button.changes
{
 "styles": [
  { "prop": "background-color",
    "variant": "primary",
    "before": "#3B82F6",
    "after": "#2563EB" },
  { "prop": "padding",
    "variant": "all",
    "before": "8px 16px",
    "after": "10px 20px" }
 ],
 "tokenCompliance": {
  "before": 0.87,
  "after": 1.0
 }
}
🟡
Button — REVIEW
2 style changes. Compliance improved 87% → 100%. Human should verify visual intent.
🟢
UserCard — PASS
No style changes. Token compliance 100%. A11y: 0 violations.
🔵
StatusBadge — NEW
New component. 4 variants. Compliance 96%. 0 a11y violations.

One command
to understand everything.

Fast, composable, CI-native. The same command that an agent runs 200 times per session is the same command that blocks your PR if a component regresses.

CI Mode
$ reactscope ci --baseline .reactscope/baseline   Manifest 47 components Renders all variants in 4.2s Compliance 93.2% (threshold 90%) A11y 0 violations Console 0 errors Visual regression: Button changed   Report → .reactscope/report/index.html exit code 0
Quick Reference
reactscope init # setup + token file reactscope manifest # build component index reactscope render Button # single render + JSON reactscope render Button --all-variants --sprite reactscope render Nav --viewports 375,768,1440 reactscope render Card --stress name reactscope instrument wasted UserList reactscope tokens compliance # full audit reactscope tokens preview color.primary.500 reactscope site serve # browse gallery reactscope report diff # change report reactscope ci # full CI run

Same data.
Every format.

JSON is canonical — everything else is derived from it. Agents get structured data. Humans get a gallery, a report, and CI checks. No divergence between what the agent sees and what you see.

Structured JSON

Every render returns DOM tree, computed styles, console output, a11y violations, token compliance, and timing. Machine-queryable, agent-native.

🖼

Sprite Sheets

Batch render output as a single annotated image. Labeled axes, flagged cells, side-by-side theme comparisons. Visual proof at a glance.

🌐

Static Gallery

Generated HTML site: component index, variant grids, token explorer, compliance reports. Built from the same data, browsable by designers.

📋

Change Reports

Before/after sprite sheets, pixel diffs, structured deltas per component. Review agent changes in one document, not a PR diff wall.

🔁

CI Integration

Non-interactive mode with exit codes. Compliance threshold failures, a11y violations, and regressions block PRs automatically.

📦

Token Exports

CSS custom properties, TypeScript constants, SCSS variables, Tailwind config, Figma variables — all generated from one token file.

Storybook shows you
components.
ReactScope understands them.

The difference between a gallery and an MRI machine.
Built for the agent doing the work. Usable by the human reviewing it.