DEVTOOLS

Debug, profile, and inspect your Storm app. Built in. One line to enable.

SETUP.TSX
import { render } from "@orchetron/storm-tui"; import { enableDevTools } from "@orchetron/storm-tui/devtools"; const app = render(<App />); enableDevTools(app);

One line. Everything wired.

That single call registers all DevTools middleware and input handlers. Press 1 through 6 to toggle each tool.

check_circle Zero overhead when not enabled -- code is tree-shaken if not imported
check_circle No separate process. No browser tab. Everything in the terminal.
check_circle All overlays are non-blocking -- the app keeps running underneath
check_circle Returns a DevToolsHandle with destroy() for clean teardown
1
Render Heatmap

Render Diff Heatmap

Overlays color on every cell based on how recently it changed. Instantly reveals which parts of your UI are causing unnecessary repaints, animation hotspots, and thrashing cells.

Heat Scale

Hot -- changed THIS frame
Warm -- changed 2-5 frames ago
Cooling -- changed 6-10 frames ago
Cool -- changed 11-15 frames ago
Stable -- unchanged 15+ frames (no overlay)

What It Reveals

  • -- Components re-rendering every frame when they should not
  • -- Animation hotspots (expected hot regions)
  • -- Stable regions the diff renderer can skip
  • -- Thrashing cells (constantly red = bug)

Live Preview

COLD
HOT cooldown: 15 frames
2
Accessibility Audit

WCAG Accessibility Audit

Real-time contrast checking across every rendered cell. Flags WCAG AA violations (below 4.5:1), invisible text (below 1.5:1), and optionally AAA violations (below 7:1). Caches contrast ratios per unique color pair.

Violation Types

contrast-aa Foreground/background ratio below 4.5:1
contrast-aaa Ratio below 7:1 (when AAA checking enabled)
invisible-text Ratio below 1.5:1 -- nearly invisible content

How It Works

  • -- Scans every cell in the rendered buffer
  • -- Caches contrast ratios per unique fg/bg pair (up to 4096 entries)
  • -- Scans every 10 frames by default to limit overhead
  • -- Violations get a red underline in the terminal
  • -- Summary bar shows score, violations, unique color pairs

Audit Output

94%
AA Score
PASS 47 cells
FAIL 3 cells
Unique Violations
fg /
bg
2.1:1 x2
fg /
bg
3.8:1 x1
[A11y Audit] Score: 94% AA | 3 violations | 2 unique color pairs
3
Time-Travel

Time-Travel Debugger

Records every rendered frame into a 120-frame circular buffer (~2 seconds at 60fps). Pause live rendering and scrub backwards and forwards through render history to see exactly what changed between frames.

Controls

Left Previous frame
Right Next frame
3 Exit time-travel, resume live rendering
Esc Exit time-travel (alternate)

Each Snapshot Records

  • -- Frame number and timestamp
  • -- Full cell buffer (chars, fg, bg, attrs, underline colors)
  • -- Terminal dimensions at capture time
  • -- Trigger type: commit, repaint, resize, animation
  • -- Paint duration and cells changed count

~50KB per frame x 120 frames = ~6MB memory

Timeline View

Frame Buffer Preview
<App> / <StatusBar> / <Text>
Frame 87/120 Age: 1.45s Trigger: commit Changed: 42 cells Paint: 0.3ms
0 Frame History 120
Left prev Right next 3 exit
4
Inspector

DevTools Overlay

A multi-panel debug overlay rendered at the bottom of the screen. Four tabs for inspecting every aspect of your running app -- tree structure, computed styles, performance metrics, and input events.

Four Panels

Tree

Collapsible component hierarchy. Shows element type, key, and layout dimensions. Selected element gets a highlight border in the main view above.

Styles

Computed props and layout for the selected element: position, size, flexDirection, padding, color, and all style props.

Perf

FPS sparkline, paint/diff/flush timing breakdown, cells changed count and percentage, budget bar showing frame time vs 16.67ms target.

Events

Ring buffer of recent input events with type (key/mouse/paste/resize), detail, and relative timestamp.

Controls

[ Prev panel
] Next panel
j Select next
k Select prev
Space Toggle collapse
4 Close overlay

Overlay Preview

Tree
Styles
Perf
Events
v App 80x24
v Box borderStyle="round" 78x22
> Spinner type="dots" 2x1
> Text bold color="#82AAFF" 16x1
> StatusBar 78x1
5 elements Selected: Spinner [j/k] navigate [Space] toggle
Deep Profiling

Performance Profiler

Per-frame timing, memory tracking, GC pressure estimation, and Storm internals. Designed for zero overhead when disabled.

5

Profiler Overlay

FPS Sparkline
60fps
Frame Timing Breakdown
layout
0.12ms
paint
0.18ms
diff
0.08ms
flush
0.05ms
Frame budget 0.43ms / 16.67ms (2.6%)
6

Export to JSON

Press 6 to dump the full profiler history to a JSON file for offline analysis.

Per-Frame Snapshot Includes

-- Layout timing (ms)
-- Paint timing (ms)
-- Diff timing (ms)
-- Flush timing (ms)
-- RSS memory
-- Heap used/total
-- GC pressure estimate
-- Cells changed/total
-- Host element count
-- Active timer count
-- FPS
-- Buffer bytes

Alerts

Register callbacks for automatic alerts:

const handle = enableDevTools(app); // Alert on high memory (> 100MB RSS) handle.profiler.onHighMemory(100, (snap) => ...); // Alert on slow frames (> 16ms) handle.profiler.onSlowFrame(16, (snap) => ...); // Alert on GC pressure handle.profiler.onGCPressure(0.8, (snap) => ...);

Memory sampled every 10th frame. History capped at 600 frames (10s at 60fps).

Crash Forensics

Post-mortem diagnostics

On unhandled exception, unhandled rejection, or fatal signal, Storm auto-saves a synchronous JSON file with everything needed to debug the crash -- even when it only happens in production.

Crash Log Contains

-- Last 60 profiler frame snapshots
-- Full component tree dump
-- Memory state (RSS, heap, external)
-- Error stack trace
-- Terminal dimensions
-- Node.js and Storm versions

Enabled by default with enableDevTools(). Disable with { crashLog: false }. Custom directory with { crashLogDir: "./crashes" }.

STORM-CRASH-2026-04-01T12-34-56.JSON
{ "timestamp": "2026-04-01T12:34:56.789Z", "error": { "name": "TypeError", "message": "Cannot read property 'x' of null", "stack": "TypeError: Cannot read..." }, "lastFrames": [ /* 60 ProfilerSnapshots */ ], "memory": { "rss": 52428800, "heapUsed": 28311552, "heapTotal": 35651584 }, "componentTree": "App > Box > ...", "terminalSize": { "width": 80, "height": 24 }, "nodeVersion": "v22.0.0", "stormVersion": "0.1.0" }

ALL BUILT IN

No npm install. No browser extension. No separate process. No browser tab. Everything runs in the same terminal, in the same process.

1 line

enableDevTools(app) -- that is the entire setup

0 overhead

Don't call it in production. The code is tree-shaken. Zero cost.

SSH

Works over SSH sessions too. Debug remote terminal apps with the same tools.