react-plotly.js
React component wrapper for Plotly.js interactive charts and graphs
Repository Health
Technical Analysis
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.
Used by 3 apps in this directory
MLflow
AI Development · Monitoring
The open source AI engineering platform for debugging, evaluating, monitoring, and optimizing production LLMs and agents at scale.
Redash
Analytics · Data Engineering
Redash lets anyone connect to 35+ SQL and NoSQL data sources, write a query in the browser, and turn the result into a shared dashboard — no separate BI suite required.
ToolJet
Low Code Platforms · No Code Platforms · AI Agents
Open-source AI-native platform to build and deploy internal tools, workflows, and AI agents with a visual drag-and-drop builder and 80+ data source integrations.