Library / SDK
d3/d3 avatar
d3/d3

D3 gives you thirty packages and no finished chart

Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:

113,776 stars22,642 forksShellISC

At a glance

What is it?
The d3 package on npm is a facade over thirty separate libraries, each one a single instrument such as a scale or a path generator. You assemble the chart yourself, and the repository hands you almost no runnable example to start from.
Who is it for?
Adopt d3 when the visualisation itself is the product and the encoding has to be yours, and stay with a higher-level library when a standard chart against a deadline is the requirement. Before anything else, resolve which version you actually get: main has received commits since 2026-05-28, but the newest published release is v7.9.0 from 2024-03-12, so check whether the fix you need exists in 7.9.0 or only on the branch.
Can I use it commercially?
Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 125 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Thirty packages behind a single index.js

The npm package named d3 is a facade, not an implementation. Its package.json lists thirty dependencies, running from d3-array and d3-axis through d3-scale, d3-shape, d3-geo, d3-force, d3-hierarchy, d3-zoom and d3-selection. Nothing in that list is a chart in the sense a reader usually attaches to the word. d3-scale maps data values onto pixel ranges. d3-shape turns an array of points into an SVG path string. d3-zoom manages viewport transforms and gesture state. The umbrella package exists so an application can depend on one name and receive all of them at mutually compatible versions, which saves thirty version ranges sitting in your own lockfile. The same convenience has a cost: a bundle built from the facade carries the packages you never call, unless you import the sub-packages directly.

Bundlers read src/index.js, a script tag reads dist/d3.min.js

package.json defines two ways in, and they are not interchangeable. Both main and module point at src/index.js, and the exports map lists a default condition resolving to that same file, so a bundler walking node_modules ends up reading unbundled ES modules. A separate umd condition, plus the jsdelivr and unpkg fields, resolve to dist/d3.min.js instead, which is the rollup and terser output. The files array publishes only dist/d3.js, dist/d3.min.js and the ES modules under src/, so test/ and docs/ never reach a consumer. One consequence shows up the first time an import fails to resolve: the tool either honoured the exports map or quietly fell back to the umd build, and those two paths hand you different module formats for the same code.

npm install d3, or name only the packages you need

No install command appears in the README, but the package name and version are unambiguous in package.json, which declares name d3 at version 7.9.0. For an application that needs the whole set, install the facade:

bash
npm install d3

Reach for the individual packages when the chart needs two of the thirty. d3-scale and d3-selection appear in that dependency list at ^4.0.2 and ^3.0.0, so both names resolve from the same registry:

bash
npm install d3-scale d3-selection

Pin the exact published version as [email protected] if a lockfile policy forbids ranges. A yarn.lock sits at the repository root, so the project installs itself with yarn, and the devDependency on @rollup/plugin-node-resolve shows the bundle is assembled from those individual packages rather than from a checked-in dist file.

The README carries no runnable example at all

Its entire body is one paragraph of positioning, a link to a daily downloads chart, and four resource links: documentation at d3js.org, examples at observablehq.com/@d3/gallery, releases on GitHub, and help at d3js.org/community. No import statement, no markup, no data array appears anywhere in it. For someone deciding whether to adopt the library, that is the real price of the low-level design. You get primitives and a promise of flexibility, and the first working line of code has to come from somewhere else. The repository does hold API.md and a docs/ directory, so the reference material is present rather than absent, but the README is what a package page renders, and that is where a prospective user starts.

You get scales and shapes, never a chart type

The repository description summarises the scope as bringing data to life with SVG, Canvas and HTML, and the README positions the approach as low-level and built on web standards while describing D3 as a building block for higher-level chart libraries. Read that sequence carefully and the consequence is clear. No bar, line or scatter chart exists in the package. You compute a scale, bind it to a selection, and draw marks yourself, and you then own axis ticks, band padding, tooltip hit testing and every redraw on resize. The trade is honest control against a large amount of code somebody else would have written for you. For a one-off internal dashboard that is rarely worth it. For a graphic whose whole point is a non-standard encoding it usually is.

The higher-level alternative already sits in devDependencies

The repository names one itself. @observablehq/plot appears in devDependencies at ^0.6.7, next to @observablehq/runtime at ^5.7.3, so the examples and tests in this tree are not built from D3 primitives alone. Plot inverts the arrangement: a chart is declared by binding data fields to visual channels, and the library works out scales, axes and layout. D3 hands over the individual instruments and expects you to conduct. The difference shows up in the first afternoon, because with Plot a bar chart is one declaration while with D3 it is a scale, an axis call, a join and a path generator. The expense runs the other direction too, since the first requirement Plot cannot express directly is where you drop down to these packages anyway.

ISC covers the facade, thirty dependencies bring their own terms

package.json declares ISC, and a LICENSE file sits at the repository root. ISC is a short permissive licence: it grants use, modification and distribution, and asks that the copyright notice travel with copies. That grant covers the facade package alone. The thirty dependencies are separate npm packages carrying their own licences, and a browser bundle that includes all of them ships all thirty notices. Nothing in this repository explains how to audit that set, and the README is silent on licensing, so the walk falls to whoever publishes the bundle. Read the LICENSE file here for the exact grant wording, and treat the dependency list in package.json as the inventory to work through.

main has moved ahead of the published v7.9.0

The default branch is main and the repository is not archived. Its last push was on 2026-05-28. The newest listed release is v7.9.0, dated 2024-03-12, and the two before it are v7.8.5 from 2023-06-03 and v7.8.4 from 2023-04-01, so the published version has not moved in more than two years while the branch kept taking commits. That gap has an exact cost. A defect repaired on main after 2024-03-12 is not in what npm hands you, and CHANGES.md at the repository root is where you would look to judge whether anything since that release concerns you. Upgrading inside v7 means staying on 7.9.0, because there is no later version to move to.

Editorial conclusion

Adopt d3 when the visualisation itself is the product and the encoding has to be yours, and stay with a higher-level library when a standard chart against a deadline is the requirement. Before anything else, resolve which version you actually get: main has received commits since 2026-05-28, but the newest published release is v7.9.0 from 2024-03-12, so check whether the fix you need exists in 7.9.0 or only on the branch.

Frequently asked questions

What is D3 in JavaScript?

A free, open-source JavaScript library for visualizing data, which its README describes as taking a low-level approach built on web standards. The repository description puts its scope as bringing data to life with SVG, Canvas and HTML.

Can I use D3 in Python?

Not from this repository as published. The package sets type to module and its entry points are src/index.js and dist/d3.min.js, both JavaScript, and the README names no Python binding.

What does D3 stand for?

Data-Driven Documents. That expansion is the README title and the description field in package.json.

Official sources

  1. d3/d3 on GitHub
  2. License: ISC
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/d3-d3.svg)](https://hysenlabs.com/projects/d3-d3)