Skip to content
plotly-js logo

Plotly.js Multi-Version Support (v1, v2, v3)

plotly-js

Use this skill when working with Plotly.js in JavaScript/TypeScript frontend projects. Covers debugging Plotly code, implementing specific chart types (candlestick, 3D surfaces, choropleth maps), React integration with react-plotly.js, and version migration between v1/v2/v3. Trigger when users me...

SKILL.md

Full skill instructions

Plotly.js Multi-Version Support (v1, v2, v3)

Rules (ALWAYS follow)

  1. NEVER write Plotly code without first detecting the version from package.json or CDN script tags
  2. If the version cannot be determined, ASK the user before writing any code
  3. Apply ONLY patterns valid for the detected version — v3 removed several APIs that v1/​v2 support
  4. Check for competing chart libraries first — if the project already uses Chart.js, Recharts, Highcharts, ECharts, Victory, ApexCharts, Nivo, or Visx for its charts, ask the user whether they want to use Plotly instead or alongside the existing library
  5. Inform the user about version limitations — if the detected version is v1 or v2, proactively mention what features they're missing and whether upgrading would be beneficial for their use case
  6. When using React, check for react-plotly.js — if not present, recommend installing it rather than doing manual DOM manipulation

Version Detection

Always run this first when starting work with Plotly.js:

# Check npm dependency
grep -E "\"plotly.js|\"react-plotly" package.json

# Also check for CDN usage in HTML files
grep -r "cdn.plot.ly/​plotly\|plotly-latest\|plotly\.js" --include="*.html" .

Extract the major version number:

const plotlyVersion = pkg.dependencies?.['plotly.js'] ||
                      pkg.devDependencies?.['plotly.js'] ||
                      pkg.dependencies?.['plotly.js-dist'] ||
                      pkg.dependencies?.['plotly.js-dist-min'];
const major = parseInt(plotlyVersion?.match(/\d+/)?.[0] ?? '');

Also check for partial bundles — Plotly ships several:

  • plotly.js — full bundle (~3.5 MB minified)
  • plotly.js-dist / plotly.js-dist-min — pre-bundled full distribution
  • plotly.js-basic-dist — basic charts only (scatter, bar, pie)
  • plotly.js-cartesian-dist — cartesian charts
  • plotly.js-geo-dist — geographic charts
  • plotly.js-gl3d-dist — WebGL 3D charts
  • plotly.js-gl2d-dist — WebGL 2D charts (removed in v3)
  • plotly.js-mapbox-dist — mapbox charts (deprecated in v3)
  • plotly.js-finance-dist — financial charts

The partial bundle determines which chart types are available. If the user tries to use a chart type not in their bundle, suggest either switching to the full bundle or the appropriate partial bundle.

Competing Library Detection

Before suggesting Plotly.js patterns, scan for existing charting libraries:

grep -E "\"chart\.js\"|\"recharts\"|\"victory\"|\"highcharts\"|\"apexcharts\"|\"echarts\"|\"@nivo\"|\"visx\"|\"d3\"" package.json

If a competing library is found, ask the user before proceeding. Plotly can coexist with other libraries, but mixing chart libraries in the same project adds bundle size and inconsistency.

Exception: d3 as a dependency does not count as a competing chart library — Plotly.js itself uses D3 internally. Only flag D3 if the user is using it directly for charting (check for d3.select patterns creating SVG charts).


Version-Specific Breaking Changes

Plotly.js v1.x (Legacy)

  • Title: Accepts plain string title: "My Chart" — this is the original format
  • Transforms: Supported (aggregate, filter, groupby, sort)
  • jQuery events: $(graphDiv).on('plotly_click', ...) works
  • AMD/​UMD: Bundle supports RequireJS and AMD loaders
  • GL traces: pointcloud and heatmapgl available
  • Mapbox: Full scattermapbox, choroplethmapbox, densitymapbox support
  • Build target: ES5
  • Note: v1 is no longer maintained. Security patches and new features only land in v2+/​v3+

Plotly.js v2.x

Key changes from v1:

  • Title format: title: { text: "My Chart" } is now the canonical form. Plain strings still work but are deprecated
  • mapbox traces deprecated (v2.35+): New map traces introduced (scattermap, choroplethmap, densitymap) using MapLibre instead of Mapbox GL JS — no access token needed
  • subtitle added (v2.34+): layout.title.subtitle for chart subtitles
  • Multiple legends (v2.22+): legend2, legend3, etc. in layout
  • zorder (v2.31+): Control stacking order of cartesian traces
  • Bar corner radius (v2.29+): marker.cornerradius for rounded bars
  • insiderange (v2.27+): Avoid tick label overlap on inner axes
  • Shape labels (v2.19+): label attribute on shapes with texttemplate
  • Container-referenced legends (v2.23+): legend.xref/yref = "container"
  • TypeScript types: Available via @types/​plotly.js (community maintained)
// v2 title (canonical form)
Plotly.newPlot('div', data, {
  title: { text: 'Revenue by Quarter', font: { size: 20 } }
});

// v2.35+ map traces (replaces mapbox)
{
  type: 'scattermap',
  lat: [45.5, 46.0],
  lon: [-73.5, -74.0],
  mode: 'markers'
}

Plotly.js v3.x (Current — latest: 3.4.0)

Major breaking changes from v2:

1. String Titles Removed (CRITICAL)
// v1-v2: Plain string works
layout: { title: 'My Chart' }

// v3: MUST use object form — string will be IGNORED
layout: { title: { text: 'My Chart' } }

// Also removed: titlefont, titleposition, titleside, titleoffset
// Use: title.font, title.position, title.side, title.offset
2. Transforms Removed (CRITICAL)
// v1-v2: Transforms API available
traces: [{
  x: rawData.x,
  y: rawData.y,
  transforms: [{ type: 'filter', target: 'y', operation: '>', value: 10 }]
}]

// v3: Pre-process data in JavaScript instead
const filtered = rawData.filter(d => d.y > 10);
traces: [{ x: filtered.map(d => d.x), y: filtered.map(d => d.y) }]
3. Deprecated Trace Types Removed
  • pointcloud — use scattergl instead
  • heatmapgl — use heatmap instead
  • gl2d subplot type removed
4. Deprecated Attributes Removed
RemovedReplacement
bardirorientation: 'h'
annotation.refannotation.xref + annotation.yref
error bar opacityUse alpha channel in error bar color
gl3d.camerapositiongl3d.camera
plot3dPixelRatio (config)Removed from config
surface.zauto/​zmin/​zmaxsurface.cmin/​cmax/​cauto
autotick on axestickmode: 'auto'
5. jQuery and AMD Support Removed
// v1-v2: jQuery events worked
$(gd).on('plotly_click', handler);

// v3: Only native events
gd.on('plotly_click', handler);

// v1-v2: AMD/​RequireJS loading worked
// v3: Only ES modules and CommonJS (require)
6. Mapbox Deprecated
// v2.35+/​v3: Use map traces (MapLibre) instead of mapbox
// scattermapbox → scattermap
// choroplethmapbox → choroplethmap
// densitymapbox → densitymap
// No access token needed for map traces
7. CSP-Friendly

v3 removed inline styles that broke strict Content Security Policy setups. If your v2 project has CSP issues with Plotly, upgrading to v3 resolves them.

8. New Features in v3
  • layout.title.subtitle: Subtitles with independent font styling
  • hovertemplatefallback / texttemplatefallback (v3.2+): Fallback templates
  • pattern.path (v3.1+): Custom SVG path patterns
  • zerolinelayer (v3.1+): Draw zero line above traces
  • hoverlabel.showarrow (v3.1+): Hide hover label caret
  • Dashed marker lines (v3.4+): Scatter plot marker line dash styles
  • Legend title click (v3.4+): Click legend title to toggle all traces
  • hovertemplate for candlestick/​ohlc (v3.3+)
  • Keyboard-accessible modebar (v3.1+)

Quick Version Reference

Featurev1.xv2.xv3.x
String titleYesYes (deprecated)Removed
title.subtitleNoYes (v2.34+)Yes
TransformsYesYesRemoved
jQuery eventsYesYesRemoved
AMD/​UMDYesYesRemoved
pointcloud / heatmapglYesDeprecatedRemoved
mapbox tracesYesDeprecated (v2.35+)Deprecated (use map)
map traces (MapLibre)NoYes (v2.35+)Yes
Multiple legendsNoYes (v2.22+)Yes
zorderNoYes (v2.31+)Yes
Bar corner radiusNoYes (v2.29+)Yes
Shape labelsNoYes (v2.19+)Yes
CSP-safe (no inline styles)NoNoYes
ES module build (esbuild)NoNoYes
pattern.pathNoNoYes (v3.1+)
MaintainedNoSecurity onlyActive

Core API Functions

These are the main Plotly.js functions — they are consistent across v1, v2, and v3:

// Create a new plot (replaces any existing one)
Plotly.newPlot(graphDiv, data, layout, config);

// Efficiently update a plot (preferred for React and dynamic updates)
Plotly.react(graphDiv, data, layout, config);

// Update trace data in-place
Plotly.restyle(graphDiv, update, traceIndices);

// Update layout in-place
Plotly.relayout(graphDiv, update);

// Combined restyle + relayout
Plotly.update(graphDiv, dataUpdate, layoutUpdate, traceIndices);

// Add traces
Plotly.addTraces(graphDiv, traces, newIndices);

// Delete traces
Plotly.deleteTraces(graphDiv, indices);

// Move traces (reorder)
Plotly.moveTraces(graphDiv, currentIndices, newIndices);

// Animate
Plotly.animate(graphDiv, frameOrGroupOrFrameList, animationOpts);

// Purge (destroy plot, free memory)
Plotly.purge(graphDiv);

// Export to image
Plotly.toImage(graphDiv, opts);       // returns Promise<dataURL>
Plotly.downloadImage(graphDiv, opts); // triggers download

// Get plot data
Plotly.makeTemplate(graphDiv);  // extract template from existing plot

Plotly.react vs Plotly.newPlot: Prefer Plotly.react for updates — it diffs the data and only redraws what changed. newPlot destroys and recreates the entire plot. React wrappers (react-plotly.js) use Plotly.react internally.


Version Upgrade Recommendations

When informing the user about their version:

If v1.x: "Your project uses Plotly.js v1 which is no longer maintained. v3 is the current release with active development, security patches, and significant new features (subtitles, map traces without access tokens, CSP support, pattern fills, better performance). Consider upgrading — see the migration guide for a step-by-step checklist."

If v2.x: "Your project uses Plotly.js v2. v3 is the current release with improved CSP support, modern ES builds (smaller bundles), and new features. The main breaking changes are: string titles must become { text: '...' }, transforms are removed (pre-process data in JS), and jQuery/​AMD support is dropped. If you rely on transforms, you'll need to refactor data processing. See the migration guide for details."

If v3.x but not latest: Mention specific features added in newer v3.x releases that may be relevant to the user's task.


Additional Resources

For a comprehensive reference of all 40+ chart types with code examples, see:

For React integration with react-plotly.js (props, state management, custom bundles), see:

For detailed migration steps from v1→v2 and v2→v3 with checklists, see:

For common patterns (responsive charts, events, animations, subplots, theming, export), see:

Official Plotly docs: