Skip to content

DevTools

Wrap your app with XNetDevToolsProvider. In production builds, it tree-shakes to zero bytes.

import { XNetDevToolsProvider } from '@xnet/devtools'
<XNetProvider config={...}>
<XNetDevToolsProvider>
<App />
</XNetDevToolsProvider>
</XNetProvider>

Toggle: Ctrl+Shift+D (or Cmd+Shift+D on Mac), or click the floating wrench button.

Browse every node in the NodeStore. Features:

  • Full-text search across IDs, schemas, and properties
  • Filter by schema type
  • Show/hide deleted nodes
  • Click a node to see its full properties, timestamps, and author DID
  • Copy all nodes as JSON

Data refreshes every 2 seconds and on live store events.

Chronological timeline of all mutations with Lamport clock ordering:

  • Color-coded by operation: green (create), blue (update), red (delete), yellow (restore), purple (remote), amber (conflict)
  • Filter by node ID or event type
  • Auto-scroll toggle to follow new events
  • Click any change for the full JSON payload

Keeps the last 1000 events.

P2P connection status and peer monitoring:

  • Connection status indicator (connected/connecting/disconnected/error)
  • Peer list with connection times
  • Sent/received/error counters
  • Scrolling event log with timestamps
  • Toggle sync debug logging (localStorage xnet:sync:debug)

Y.Doc structure inspector with three sub-views:

  • Updates — Live stream of Yjs update events with local/remote indicators and byte sizes
  • Structure — Interactive tree view of Y.Doc shared types (Map, Array, Text, XmlFragment). Expandable nodes, color-coded by type, depth-limited to 5 levels.
  • State Vectors — ClientID clock values with progress bars. Shows how far each peer has synced.

Select a document from the sidebar to inspect its internals.

Performance profiler for all active hooks:

  • Lists every useQuery, useMutate, and useNode instance
  • Shows schema, mode (list/single/filtered/document), caller source location
  • Tracks update count, result count, average and peak render time
  • Warnings: amber for >16ms (dropped frame), red for >50ms
  • Sort by most updates, slowest render, or most recent

Source locations are extracted from stack traces automatically.

Security events and performance metrics, split into three tabs:

  • Security — Network health score, crash entries, security events by severity, peer reputation scores with breakdown
  • Performance — Metric groups with bucket distribution charts (time ranges: <10ms, 10-50ms, 50-100ms, etc.)
  • Consent — Current telemetry tier (off/local/crashes/anonymous)

All registered schemas and their properties:

  • Schema list with node counts and property counts
  • Property details: type (color-coded), required flag, config summary
  • Raw schema JSON dump
  • Built-in vs. user-defined badges

Create sample data for testing:

  • Create Sample Page — Rich document with headings, lists, callouts, code blocks, Mermaid diagrams, comments with text anchors, and change history
  • Create Sample Database — 15-column database with all property types, 5 rows, view configs, and comments

Full change history and time travel for individual nodes. Seven sub-tabs:

  • Timeline — Scrub through all changes with a slider. See materialized state at any point.
  • Diff — Compare two points in time. Shows added/modified/removed properties with before/after values.
  • Blame — Per-property attribution: who last changed each field, when, and how many times.
  • Audit — Filterable audit log with operation breakdown (create/update/delete/restore).
  • Verification — Check hash chain integrity. Reports valid/invalid, verified hashes, chain links, forks.
  • Storage — Storage metrics, prunable changes, estimated recovery bytes.
  • Document — Yjs snapshot timeline. Compare snapshots with size deltas and content diffs.
<XNetDevToolsProvider
defaultOpen={false} // Start open
defaultPanel="nodes" // Initial panel
position="bottom" // 'bottom' | 'right' | 'floating'
height={320} // Panel height in pixels
maxEvents={10_000} // Ring buffer capacity
telemetryCollector={collector}
consentManager={consentMgr}
>
MethodDescription
Ctrl+Shift+DKeyboard shortcut
Floating buttonClick the wrench icon (draggable)
4-finger tapMobile
useDevTools().toggle()Programmatic

The panel remembers its state in localStorage:

  • xnet:devtools:open — open/closed
  • xnet:devtools:panel — last active tab
  • xnet:devtools:position — dock position

All instrumentation flows through a DevToolsEventBus — a typed ring buffer (default 10,000 events):

const { eventBus } = useDevTools()
// Subscribe to all events
eventBus.subscribe((event) => console.log(event))
// Subscribe to a specific type
eventBus.on('sync:peer-connected', (event) => { ... })
// Query
eventBus.getEventsByType('store:create')
eventBus.getEventsForNode(nodeId)
eventBus.getRecent(50)
CategoryEvents
Store (7)store:create, store:update, store:delete, store:restore, store:transaction, store:remote-change, store:conflict
Sync (6)sync:status-change, sync:peer-connected, sync:peer-disconnected, sync:change-received, sync:broadcast, sync:error
Yjs (4)yjs:update, yjs:meta-change, yjs:state-vector, yjs:provider-status
Query (6)query:subscribe, query:unsubscribe, query:result, query:error, mutate:start, mutate:complete
Telemetry (6)telemetry:crash, telemetry:usage, telemetry:security, telemetry:performance, telemetry:consent-change, telemetry:peer-scores

Instrumentation functions connect data sources to the event bus:

instrumentStore(store, eventBus) // NodeStore events
instrumentSync(provider, room, bus) // SyncProvider events
instrumentYDoc(doc, docId, bus) // Y.Doc updates
instrumentTelemetry(collector, consent, bus) // Telemetry

React hooks (useQuery, useNode) automatically report to DevTools when the provider is present, via InstrumentationContext. No manual wiring needed.

const {
isOpen,
toggle,
eventBus,
activeNodeId,
setActiveNodeId,
activePanel,
setActivePanel,
store,
yDocRegistry
} = useDevTools()

When NODE_ENV is production, the DevTools provider renders children unchanged and useDevTools() returns inert stubs. The full panel code is tree-shaken out of the bundle — zero bytes in production.