thcThought Control

Perspective

WebAssembly streaming query engine with live grids, pivots and charts.

perspective-dev.github.io ↗repo ↗docs ↗Benchmarks (published per release as Arrow) ↗Save/restore viewer config ↗PR #3209: LLM agent for <perspective-viewer> ↗OpenJS Foundation announcement ↗

license
Apache-2.0. Moved from FINOS (where J.P. Morgan contributed it) to the OpenJS Foundation as an Incubating Project (2025-10-30); repo moved from finos/perspective to perspective-dev/perspective.
language
C++ engine compiled to WebAssembly, Rust (viewer, client), TypeScript, Python bindings
backing
OpenJS Foundation (incubating); originally J.P. Morgan; lead maintainer Andrew Stein (texodus, 3,883 commits), co-founder of The Prospective Company.
stars
11,282 (as of 2026-10-09)
downloads
npm/week: @perspective-dev/client 16,085, @finos/perspective 13,967, @perspective-dev/viewer 10,839; PyPI perspective-python 5,680/week (2026-10).
latest release
v5.5.1, 2026-09-18
first release
2019-04
borrow

Best-in-class streaming data component whose agent and schema patterns scene should copy; it is a web widget, not a terminal UI runtime, though its Rust crate could back a scene data source.

Borrow from it: take a specific idea, API or format.

the steelman: the best honest case for it

Perspective is what live data viz looks like when it is engineered by people who had to show trading desks real-time books: a C++ incremental query engine in WebAssembly, so pivots, filters and expressions recompute on each update without a server round trip, and charts render in WebGL. The view is pure data: one JSON config captures everything a user built with drag and drop, and the same client API runs in-process, in a worker or over a socket, even against DuckDB or ClickHouse without copying data. It publishes reproducible benchmarks for every release as data you can open in Perspective itself. And it has already done the agent move properly: a first-party LLM agent that drives the viewer only through its public, schema-checked config API, with local-model support. It now sits in a neutral foundation under Apache-2.0.

scores
datadriveseeedittimeratetermpxteachmatureopen
UI as data4 scene 5Each viewer is a JSON config; a whole app layout is still host code.
Agent can drive it3 scene 5First-party in-page agent API, but no external protocol/MCP.
Agent can see it4 scene 5
Small, targeted edits4 scene 5
Time travel0 scene 0
Live data rate4 scene 5Built for streaming and data bypasses the model, but no published ticks/second figure; per-op timings only.
Terminal native0 scene 5
Pixel graphics5 scene 4WebGL charting with 15+ chart types and tile maps.
Teaching1 scene 3Not a teaching tool.
Maturity4 scene 1
Openness5 scene 4Apache-2.0 under the OpenJS Foundation.

Perspective scene now scene planned

how agents use it

How

In-page: viewer.agentConfig({...provider, apiKey, docs}) then viewer.agentPrompt('Show me Sales by Region as a bar chart') runs tool calls against the viewer's public API; tool activity is emitted as perspective-agent-tool events. Externally: any agent that can call JS (or the Python/Rust client over WebSocket) can save()/restore() JSON configs and push table updates. No MCP server found.

Wiring it in

Low inside a web page (opt-in, bring a provider key or local model); for an external agent, a small bridge exposing restore/save/update.

Seeing the result

save() returns full viewer config; view.to_json/to_arrow/to_columns return data; schema via table.schema().

Small edits

restore() accepts partial ViewerConfigUpdate; table.update() with an index patches rows in place.

History

None; no undo or recorded history for viewer configs or data.

In short

Streaming data and a JSON-addressable view config make it very agent-friendly; the built-in agent proves it, but it lives inside the browser page.

architecture

A C++ columnar engine (WASM in the browser, native in Python/Rust) holds Tables that accept incremental updates (Arrow, CSV, JSON); Views over a table (group_by, split_by, filters, sorts, ExprTK expressions, windows) recompute incrementally and notify on update. The client/server API is symmetric: the same calls work in-process, in a Web Worker, or over WebSocket, and large datasets can stay server-side with only the visible window streamed. <perspective-viewer> is a Custom Element whose whole configuration (plugin, columns, pivots, filters, expressions, theme) is a JSON ViewerConfig obtained with save() and applied with restore(). Virtual servers translate view configs into DuckDB, ClickHouse, PostgreSQL or Polars queries.

performance

Measured, reproducible per-operation timings are published for every release, on a whole sample dataset (Superstore). No headline 'updates per second' or ticks-per-second figure is published, so streaming rate must be inferred; the updates bypass any model or UI framework.

adoption and upkeep

Adoption

A niche but serious tool, strongest in financial services trading/analytics dashboards (OpenJS announcement). Download numbers are modest compared with general charting libraries.

Used by: J.P. Morgan (origin)

Maintainability

Active with a fast major-version pace (v4 Oct 2025, v5 Jul 2026), but concentrated in one lead.

Releases: Roughly weekly to biweekly in 2026: v5.0.0 2026-07-28, v5.2.0 2026-08-10, v5.3.0 2026-08-25, v5.4.0 2026-09-09, v5.5.0 2026-09-15, v5.5.1 2026-09-18. · Contributors: ~104 (GitHub, incl. anonymous) · Recent: 100+ commits and 32 merged PRs since 2026-07-11. · Bus factor: low-medium: texodus has ~3,900 commits vs 884 and 453 for the next two; foundation home mitigates.

weaknesses
and thc-scene

Overlap

High-rate data streams that bypass the model, bound to views whose configuration is a JSON value an agent can read and rewrite.

What scene would be reinventing

Incremental streaming tables with pivots/aggregates/expressions; if scene needs analytics over streams, Perspective's engine (also available as a Rust crate) already does it far better than ad-hoc stream coalescing.

The gap it leaves

Terminal-native rendering, agent control over a local socket of the whole UI (not one widget), screen-as-text readback, teaching tours and time travel.

What to borrow

  • Generate JSON schemas for the config/patch types and hand them to the agent as tool parameter schemas (as PR #3209 does).
  • Ship a docs bundle (BM25-searchable JSON) with the binary for agent retrieval.
  • Publish benchmarks per release as data files, and view them in the tool itself.
  • Partial config updates (ViewerConfigUpdate) vs full initial config as two distinct typed operations.
sources
  1. Perspective README github.com
  2. Perspective benchmarks guide perspective-dev.github.io
  3. benchmark-js.arrow (v5.5.1 release asset) github.com
  4. PR #3209 LLM Agent for <perspective-viewer> github.com
  5. OpenJS: Perspective joins as Incubating Project (2025-10-30) openjsf.org
  6. Discussion #3077: joining OpenJS and v4.0.0 github.com
  7. Save/restore docs perspective-dev.github.io
  8. GitHub API perspective-dev/perspective api.github.com
  9. npm downloads @perspective-dev/client api.npmjs.org