Skip to content

Repository files navigation

orbit

npmnpm downloadsCIlicense

A typed, declarative React library for rendering and exploring graphs with WebGL. Handles 100K+ node graphs. UI components included: search, tables, histograms, and more.

orbit — a graph rendered by orbit

Why orbit

PillarWhy it matters
Declarative end to endThe graph is a prop — rendering, force layout, transitions, selection, and undo/redo are handled. No imperative canvas code.
Built for large graphsGPU rendering holds 100K+ nodes interactive; incremental filtering keeps the core's per-brush cost near 1 ms at that scale, measured on a disclosed reference machine.
Analyst UI included13 packaged components — search, minimap, tables, histograms, timelines, legends, inspectors, and more. Headless-styleable, one import each.
Testable without WebGLA headless core and an engine seam with a FakeEngine double; integration tests run in plain jsdom.
Typed, honest boundariesMalformed data degrades with batched diagnostics — never throws mid-render.
npm install @modernrelay/orbit-react @modernrelay/orbit-core @modernrelay/orbit-engine-cosmos

Status:0.15.0 on npm — all five packages release in lockstep. See Releases for changelogs.

Packages

PackageRole
@modernrelay/orbit-coreHeadless core: validation, reconciliation, projection, the instance + store. Subpaths: /engine (the GraphEngine contract), /testing (FakeEngine, worker double). No React or engine imports.
@modernrelay/orbit-react<Graph/>, GraphProvider, 13 packaged UI components, hooks, ref API. React 18+ peer.
@modernrelay/orbit-engine-cosmosThe default rendering engine: WebGL drawing and GPU force simulation, built on cosmos.gl. Loaded lazily when the graph mounts.
@modernrelay/orbit-dataPrepared-data adapters: rows/CSV/JSON in the root entry; Arrow and Parquet as isolated subpath entries that never reach the root bundle.
@modernrelay/orbit-omnigraphOmnigraph server adapter: streamed export loader, .pg schema tooling, search service.

UI components

Built into <Graph/> itself — no extra imports:

  • DOM labels with collision-ranked visibility and a renderNodeLabel custom renderer
  • Lasso selection (freehand polygon)
  • Emphasis ring for hover, focus, and keyboard navigation
  • Drag & pin handles on nodes
  • LiveRegion — screen-reader announcements for selection and navigation

Packaged components — each ships as its own entry point (@modernrelay/orbit-react/components/<Name>), headless-styleable, wired through GraphProvider context:

ComponentEntryWhat it does
GraphSearchcomponents/SearchSearch box with debounced queries, result list, keyboard activation
GraphNavigatorcomponents/NavigatorBounded semantic keyboard navigator (arrow/paging traversal with a11y announcements)
GraphMinimapcomponents/MinimapWhole-graph thumbnail with a draggable viewport rectangle
GraphTooltipcomponents/TooltipHover card for nodes and edges
GraphInspectorcomponents/InspectorDocked detail panel for the focused/selected entity
GraphTablecomponents/TableVirtualized tabular view of nodes or edges, crossfilter-connected text filtering
GraphHistogramcomponents/HistogramCrossfilter histogram — drag-brush a numeric dimension to filter the graph
GraphTimelinecomponents/TimelineTimeline band over a temporal dimension with brush + playback
GraphLegendcomponents/LegendLegend over any scale-valued styling channel, row-click filtering
GraphToolbarcomponents/ToolbarCamera & simulation controls: zoom, fit, reset, pause/resume
GraphContextMenucomponents/ContextMenuRight-click / long-press menu on nodes, edges, and background
GraphSelectionActionscomponents/SelectionActionsAction panel that appears while a selection is non-empty
GraphSimControlscomponents/SimControlsForce-simulation tunables panel (live, no restart)

Features

  • Data & identity: typed snapshots (objects or columnar), streaming ingest, validation diagnostics, stable identity across updates.
  • Layout & simulation: GPU force layout or fixed coordinates, live tunables, pause/resume, zero rAF at rest.
  • Interaction: node/edge picking, drag, lasso, pins, context menus, full keyboard navigation with a11y.
  • Exploration: scope/isolate, node expansion, groups with collapse, folds, semantic zoom, path emphasis, search.
  • Filtering & analytics: incremental crossfilter brushing, hide/dim masks, metrics, scales and legends.
  • Appearance: hot-swappable dark/light themes, node image sprites, edge arrows, animated transitions.
  • Persistence & export: deep-linkable view state, undo/redo, SVG / streamed JSON / PNG exports.
  • Scale: measured performance gates, telemetry snapshots, degradation ladder, off-main-thread data acceptance.

Hooks & imperative API

All hooks read the instance through GraphProvider (or the nearest <Graph/>):

HooksSurface
useGraphInstance, useResolvedInstanceThe headless instance itself
useGraphStatus, useGraphDiagnosticsLifecycle + batched diagnostics
useGraphSelection, useGraphHover, useGraphEdgeHover, useGraphPinsInteraction state
useGraphViewport, useGraphSimulationRunningCamera + simulation state
useGraphScope, useGraphOverlays, useGraphPendingExpansionsExploration state
useGraphVisible, useGraphCrossfilter, useGraphTimelineFiltering state
useGraphHistory, useGraphSearch, useGraphThemeHistory, search, theme

Beyond hooks:

  • GraphHandle (ref on <Graph/>): camera ops, focusNode, emphasizeNode, fold/expand/group ops, getViewState/setViewState, exports, getPerfSnapshot
  • createGraphInstance (core): the same engine-driving instance with no React — everything except the React component layer works headless (data, layout, interaction events, exploration ops, filtering, view state, exports, telemetry)

Development

pnpm install
pnpm check # boundaries + anchor/pin guards + lint + types + tests + gate evaluator
pnpm demo:dev # demo app at http://localhost:5199
pnpm --filter orbit-demo e2e # Playwright suite
node scripts/perf-lite.mjs --tier S # perf measurement (headful, real GPU only)

Ground rules enforced by pnpm boundaries and the test suites:

  • React never touches per-node hot data; buffers stay below the adapter line
  • Core imports no React; nothing outside orbit-engine-cosmos imports cosmos
  • One applyHostUpdate = one store publication = at most one atomic engine commit
  • Position readback is per-event, never per-tick
  • Perf numbers count only from real GPUs, n≥3 runs, variance-qualified — software rasterizers are never accepted

Integration testing: swap the engine for the bundled double — import { FakeEngine } from '@modernrelay/orbit-core/testing' — and the full component tree runs without WebGL.

About

A typed, declarative React library for rendering and exploring graphs with WebGL. Handles 100K+ node graphs. UI components included.

Topics

Resources

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages