react-plotly.js

React component wrapper for Plotly.js interactive charts and graphs

Library
npm
v4.1.0
1,091stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
84/100Excellent
Development Activity88
Maintenance72
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
84/100Excellent
Architecture82
Code Quality80
Innovation84
Learning Curve88

react-plotly.js is the official React binding for Plotly.js, the open-source charting library used across data science and BI tooling. It renders any Plotly.js chart type — scatter, bar, heatmap, 3D, geographic, financial — as a single <Plot> component that accepts data, layout, config, and frames as plain-object props, and keeps the underlying graph div in sync via Plotly.react whenever those props’ identity changes.

The component forwards refs to the raw graph DOM node, exposes onInitialized/onUpdate/onPurge lifecycle callbacks for capturing user-driven changes (zoom, pan, legend toggles) back into React state, and re-exports every plotly.js event (click, hover, selection, slider, legend clicks, and more) as typed on* props. A separate factory export lets consumers bind the component to a custom plotly.js bundle to control client bundle size.

What You Get

  • A single <Plot> component covering all plotly.js chart types (scatter, bar, box, heatmap, 3D, choropleth, candlestick, and more)
  • Declarative data/layout/config/frames props that diff via shallow identity checks and only re-render Plotly when they actually change
  • Lifecycle callbacks (onInitialized, onUpdate, onPurge) that hand back the current figure state after every Plotly.react call
  • Typed on* props for all plotly.js events (click, hover, selection, legend, slider, animation) generated from a single event registry
  • A factory export for binding the component to a custom or partial plotly.js bundle to cut client bundle size
  • Built-in window-resize handling via the useResizeHandler prop

Common Use Cases

  • Embedding interactive scientific or financial charts (scatter, candlestick, 3D surface) in a React dashboard
  • Building internal analytics/BI tools that need drill-down interactivity (click, hover, selection callbacks) on top of chart data
  • Rendering Plotly figures produced by a Python/R backend (e.g. via Dash or a notebook export) inside a React frontend
  • Adding responsive, resizable charts to a SaaS product without hand-rolling D3 or canvas code

Under The Hood

Architecture: factory.js exports a plotComponentFactory(Plotly) function that produces a forwardRef-wrapped React component bound to a specific plotly.js instance; the default export in react-plotly.js binds it to the full plotly.js/dist/plotly bundle. Lifecycle is driven by a single dependency-less useEffect that mirrors the old componentDidMount/componentDidUpdate pair — a prevRef snapshot diffs data/layout/config/frames identity and the optional revision prop to decide whether to call Plotly.react. Calls are serialized through a promiseRef promise chain so overlapping renders never race against each other, and a separate cleanup effect handles unmount (purging the plot, removing listeners, resetting refs so React StrictMode’s double-invoke looks like a fresh mount). events.js is the single source of truth mapping plotly.js event names to React on* prop names and to the subset that should re-trigger onUpdate, consumed by both the runtime listener wiring in factory.js and, by convention, the hand-maintained types in factory.d.ts.

Tech Stack: Targets React 18/19 as a peer dependency, hooks-only (no class components), and plotly.js ^3.0.0 as the other peer dependency — the package ships zero bundled runtime dependencies of its own. Built with tsup into dual ESM/CJS output (dist/index.mjs, dist/index.cjs) plus hand-written declaration files (index.d.ts/factory.d.ts), with TypeScript 5.9 used purely for typing since the source itself is plain JS transformed via Babel presets. ESLint 9 (flat config) and Prettier enforce style; the whole source tree is under 300 lines across four files.

Code Quality: Tests live under src/tests (a 323-line react-plotly.test.js plus events.test.js) built on @testing-library/react, jest, and jsdom, backed by a hand-rolled EventEmitter mock of plotly.js (src/mocks/plotly.js) so event wiring can be exercised without a real chart renderer. CI (.github/workflows) runs the suite across a React 18 and React 19 matrix on every push/PR. Inline comments throughout factory.js explain non-obvious decisions — frozen default props for referential stability, promise chaining to serialize Plotly.react calls, and StrictMode-safe cleanup — which raises the maintainability bar well above the code’s small size would suggest.

API Design: The public prop shape mirrors plotly.js’s own data/layout/config/frames objects directly, so existing Plotly figures (including ones generated server-side by Dash or a notebook) drop in unchanged. A forwarded ref resolves to the raw graph <div>, giving direct access to low-level Plotly.* calls when the wrapper’s API isn’t enough. Every plotly.js event is exposed as a conventionally-named on* prop generated from one source-of-truth list, and the factory export lets bundle-size-sensitive consumers swap in a smaller plotly.js build. The README documents the full prop surface with tables and worked examples, so most usage needs no external docs.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search