Library / SDK
observablehq/plot avatar
observablehq/plot

Observable Plot: a layered grammar of graphics for JavaScript

A concise API for exploratory data visualization implementing a layered grammar of graphics

5,397 stars245 forksHTMLISC

At a glance

What is it?
Observable Plot is an ISC-licensed JavaScript library for exploratory visualization of tabular data, built around layered marks and scales. Here is how it installs, what it does well, and where it stops being the right tool.
Who is it for?
Adopt Observable Plot when you need to build many small exploratory charts in JavaScript from arrays of objects, and when an SVG output you can inspect in the DOM is acceptable. Do not adopt it if you need a Python plotting library, a dashboard framework, or a chart type the mark set does not cover.
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 28 days ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

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

DEEP OPEN-SOURCE ANALYSIS

What Observable Plot is for, and who ends up using it

Observable Plot is a JavaScript library for visualizing tabular data, and the README states its focus plainly: accelerating exploratory data analysis. That word, exploratory, sets the audience. The library is aimed at people who write a lot of throwaway charts while looking for a pattern, not at people assembling a polished report where every pixel is specified in advance.

The API is described in the README as concise, memorable and expressive, with scales and layered marks in the grammar of graphics style. In practice that means you describe a chart as a set of marks (dots, bars, lines, areas, text) bound to accessor functions over your data, plus scales that map data values to positions, colors and sizes. The grammar of graphics framing matters because it separates the data mapping from the geometry, so the same data can be redrawn with a different mark without rewriting the chart.

It is a browser-oriented library. The package publishes an ES module entry at src/index.js and a UMD bundle at dist/plot.umd.min.js, which is also what the jsdelivr and unpkg fields point at. That combination covers bundler-based projects and plain script tags. The repository is written in HTML per its primary language field, which is a quirk of how the project counts its files rather than a statement about the runtime.

How marks, scales and the SVG output fit together

A Plot chart is constructed by calling Plot.plot with an options object. Marks are passed in an array, and each mark receives the data plus accessors for the channels it uses. Scales are inferred from the data unless you supply them. The result is an SVG element, and the library returns it rather than appending it for you, so you decide where it goes in the document.

The layering is the important part. Marks are drawn in the order given, so a text mark placed after a dot mark sits on top of it. Because scales are shared across marks in the same plot, a bar mark and a rule mark can reference the same y scale and stay aligned without manual coordinate math. That is the mechanism the grammar of graphics buys you here: one scale definition, many marks.

The repository layout supports this reading. The src directory holds the implementation, test holds the Vitest suite, and the docs directory is a VitePress site, which is what the docs:dev, docs:build and docs:preview scripts drive. The build itself is Rollup, invoked by prepublishOnly, which removes dist and rebuilds it. The published files list is narrow: dist JavaScript, plus src JavaScript and type declarations. TypeScript users get types from src/index.d.ts, and the test script runs tsc alongside the Vitest and lint checks.

Installing Observable Plot from npm and drawing a first chart

The package is published as @observablehq/plot. The README points to the documentation site for usage; the package metadata gives the install identity. The package.json name field is the authoritative source for what to install:

json
{
  "name": "@observablehq/plot",
  "version": "0.6.17",
  "license": "ISC",
  "type": "module",
  "main": "src/index.js",
  "module": "src/index.js",
  "jsdelivr": "dist/plot.umd.min.js",
  "unpkg": "dist/plot.umd.min.js"
}

Those fields are the whole story of how the library loads. The main and module fields both point at src/index.js, so the ES module is the default entry, and the jsdelivr and unpkg fields both point at dist/plot.umd.min.js, so a CDN that honors either field serves the UMD build for script tags. The exports field in the same file names umd and default, mapping to those two files.

The README does not include a getting-started snippet, so the first real use is a trip to the documentation site at observablehq.com/plot/ and the Plot gallery the README links to. That gallery is where the mark names and their options are demonstrated; pick the chart closest to what you need and adapt its data. There is no install command in the README, and the package name above is the identity you pass to whichever package manager you use.

Where Observable Plot stops being the right tool

Plot is not a dashboard framework. It renders a chart and hands you an SVG element. There is no data fetching layer, no reactive re-render when a filter changes, and no layout system for arranging several charts into a page. If your requirement is a linked set of views that update together, you are building that coordination yourself or using a different tool.

It is also not a Python library. The related searches include "Observablehq plot python", and the repository gives no Python package. Observable Plot is JavaScript, published to npm. If your analysis lives in a Jupyter notebook, this is the wrong dependency, and search results conflate it with other plotting systems that share the word plot.

The release cadence is worth stating as a fact rather than a warning. The most recent release listed is v0.6.17, published on 2025-02-14, following v0.6.16 on 2024-08-06 and v0.6.15 on 2024-06-11. The repository is not archived and the last push was on 2026-09-01, so the codebase is moving even though the version number has not. The version is still 0.x, which tells you the maintainers have not declared a stable API. Expect occasional breaking changes between minor versions and read the CHANGELOG before upgrading in a project you cannot easily patch.

How Plot differs from reaching for D3 directly

The obvious alternative is D3, and the related searches include "Observablehq d3" because the two are frequently mentioned together. The difference is the level of abstraction, and it is a real one.

D3 gives you selections, scales and shape generators, and you assemble the chart yourself: create the SVG, append a group, bind data, set attributes, handle the axes. That control is the point when you need a bespoke visual or a custom interaction. Plot sits above that layer. You declare marks and scales, and the library produces the SVG. You give up per-element control over the markup in exchange for far less code per chart.

That trade is why Plot suits exploratory work and D3 suits one-off bespoke graphics. If you find yourself fighting Plot to get a specific element positioned exactly, that is a signal you wanted D3. If you are writing the same axis boilerplate for the tenth time, that is a signal you wanted Plot. The two are not exclusive; Plot is built in the same ecosystem, and the repository depends on @types/d3 in development.

Maintenance, upgrade cost and the ISC licence

The package is licensed ISC, and the LICENSE file is at the repository root. ISC is a permissive licence in the same family as MIT: it allows use, modification and redistribution provided the copyright notice and permission notice are retained. That is a summary of the licence text, not legal advice; if your organization has a policy on permissive licences, run it past whoever owns that policy.

Upgrade cost is the practical question. The version is 0.x, so semver's stability guarantees do not apply in the way they do from 1.0 onward. The CHANGELOG files are split by year (CHANGELOG-2021.md through CHANGELOG-2024.md, plus a current CHANGELOG.md), which makes it straightforward to read what changed between the version you have and the version you want. Budget for reading that file rather than assuming a patch bump is inert.

The dependency surface is small for consumers: the published files are dist JavaScript plus src JavaScript and .d.ts declarations. The heavy toolchain in package.json (Rollup, Vite, Vitest, ESLint, Prettier, TypeScript) is development-side. You inherit the runtime, not the build. The test script chains Vitest, tsc, ESLint and Prettier, and the coverage run pins TZ=America/Los_Angeles, which suggests time-zone-sensitive behavior in the test suite worth knowing if you contribute.

Editorial conclusion

Adopt Observable Plot when you need to build many small exploratory charts in JavaScript from arrays of objects, and when an SVG output you can inspect in the DOM is acceptable. Do not adopt it if you need a Python plotting library, a dashboard framework, or a chart type the mark set does not cover. Before committing, check the CHANGELOG for the mark you intend to use, confirm the current version on npm, and read the LICENSE file, which is ISC and permits reuse with the notice retained.

Frequently asked questions

What is an Observable Plot?

It is a free, open-source JavaScript library for visualizing tabular data, focused on exploratory data analysis. It offers scales and layered marks in the grammar of graphics style, and returns an SVG element you place in the page yourself.

What is the purpose of plotting data?

The README frames the library's purpose as accelerating exploratory data analysis, which is the stage where you draw many quick charts to find structure in tabular data before committing to a final graphic.

What language does Observable Plot use?

Observable Plot is a JavaScript library, published to npm as @observablehq/plot with an ES module entry and a UMD bundle. The repository's primary language field says HTML, which reflects how its files are counted rather than the runtime language.

Official sources

  1. License: ISC
  2. observablehq/plot on GitHub
  3. Project website
  4. README
  5. Releases
For maintainers

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/observablehq-plot.svg)](https://hysenlabs.com/projects/observablehq-plot)
Community notes

Community notes