Observable Plot composes charts from layered marks and scales
A concise API for exploratory data visualization implementing a layered grammar of graphics
At a glance
- What is it?
- A free JavaScript library from Observable for reading tabular data in a browser, built on two ideas, scales and layered marks in the grammar of graphics style. It is a compact 0.x package with an 88 word README, an unbundled default export, and a version field that still reads 0.6.17 from February 2025.
- Who is it for?
- Use Observable Plot when you want one small JavaScript dependency for exploratory charts built from marks and scales, and when you are willing to learn it from the documentation site rather than from the repository. Leave it alone if you need a frozen public API, or a component wrapper for a UI framework, and check which commit you actually install, because the registry version 0.6.17 predates the last push to main.
- 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 8 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 November 13, 2026, and from our analysis. They are not legal advice.
Star history
- observablehq/plot5,425 ★ · +38
| Repository | 2026-09-23 | 2026-11-13 |
|---|---|---|
| observablehq/plot | 5.4k | 5.4k |
38 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Scales and layered marks are the whole vocabulary
The repository description is a concise API for exploratory data visualization implementing a layered grammar of graphics. The README narrows the scope to tabular data and names a focus on accelerating exploratory data analysis, then links two documentation pages, one for scales and one for marks, both under a features path. Those two nouns are the framing the project puts in front of you, which means the library is assembled from a small set of parts rather than picked from a list of named chart templates. The trade is real: there is little to memorize, but every option you eventually need lives on those two pages off the repository, so the tree itself will not tell you which properties a mark accepts. The package is published to npm as @observablehq/plot under an ISC license, authored by Observable, Inc.
An 88 word README with no install line
The README in this repository is 88 words long. It states what the library is, embeds a badge for the daily download count of @observablehq/plot, and then lists five links: the documentation site at observablehq.com/plot/, a plot gallery at observablehq.com/@observablehq/plot-gallery, the changelog and release notes, a community guide, and CONTRIBUTING.md. There is no install line, no import statement, and no code block anywhere in it, so there is nothing to copy out of the repository to start a project. A reader holding only a clone has no documented route to a first chart, and the running examples live on two external sites instead of in the tree. If your only input is the repository, the manifest name is the single usable fact:
npm install @observablehq/plot
pnpm add @observablehq/[email protected]The default export is unbundled source, not the bundle
The manifest decides what your bundler actually receives, and for Plot the answer is not what most people expect. The package declares type module, and both main and module resolve to src/index.js rather than to a built file. The exports map has exactly two entries: a umd condition pointing at ./dist/plot.umd.min.js and a default condition pointing back at ./src/index.js, with types at src/index.d.ts. An application importing the package through a bundler therefore compiles Plot from its own ES modules, and only a consumer that explicitly asks for the umd condition gets the single minified file. The jsdelivr and unpkg fields both point at that same UMD artifact. The files array ships dist, the declaration files, and the source, so the docs tree, the per-year changelog files, and CONTRIBUTING.md never reach the tarball. The manifest also marks only ./src/index.js as side effecting, which is how a bundler knows not to discard the entry module.
The version field still reads 0.6.17 from February 2025
Two timelines run in this repository and they do not meet. The version field in package.json reads 0.6.17, and the three most recent tags are v0.6.15 dated 2024-06-11, v0.6.16 dated 2024-08-06, and v0.6.17 dated 2025-02-14. The default branch main, however, was last pushed on 2026-10-30. That gap has a direct effect on what you install: pulling from the registry hands you code tagged in February 2025, not the state of the tree today, and reaching main means installing from the repository or from a commit URL. The spacing between tags also widened, from roughly two months between v0.6.15 and v0.6.16 to roughly six before v0.6.17. The package remains 0.x with no 1.0 tag, so nothing in the numbering promises a stable public API across a major bump.
Four test gates chained through pnpm
Contributing to Plot means clearing four gates in one sequence, and the chain stops at the first failure:
"scripts": {
"test": "pnpm run test:vitest run && pnpm run test:tsc && pnpm run test:lint && pnpm run test:prettier",
"test:coverage": "TZ=America/Los_Angeles vitest run --coverage",
"test:vitest": "TZ=America/Los_Angeles vitest --typecheck",
"test:lint": "eslint src test",
"test:prettier": "prettier --check src test",
"test:tsc": "tsc",
"prepublishOnly": "rm -rf dist && rollup -c",
"dev": "vite",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
}Formatting counts as a gate, since prettier runs in check mode over src and test, so a diff that does not match prettier's formatting fails. Both vitest scripts pin TZ to America/Los_Angeles, which means any date dependent behaviour in the suite is only reproducible under that zone and can disagree with a machine set elsewhere. The root holds pnpm-lock.yaml and pnpm-workspace.yaml with no package-lock.json, so the scripts, which all route through pnpm run, reproduce only under pnpm.
Docs are built from the tree, not from a tag
Documentation sits inside the same repository as the code, which is convenient until you want to learn one specific release. The docs directory is served by VitePress through three scripts, while vite handles the library side, and the root also carries vite.config.js, vitest.config.ts, and rollup.config.js. The published build is produced only at publish time, because prepublishOnly removes dist and then runs rollup, and no dist directory is checked in. Because the docs tree lives on main beside unreleased code, a docs build from main can describe an option that the released v0.6.17 package does not implement. The project is also tagged as HTML at the repository level while the published package is JavaScript, which matches a tree where docs/, img/, and test/ sit beside src/. No examples directory exists at the root; the copy and paste gallery is hosted separately.
A changelog split by year and a blame rewrite file
Release history in this repository is fragmented by year. The root holds CHANGELOG-2021.md, CHANGELOG-2022.md, CHANGELOG-2023.md, CHANGELOG-2024.md, and a current CHANGELOG.md, and the README sends readers to that last file plus the release notes pages on the forge. Finding what changed in an older release means guessing which year file covers it, and auditing the last three tags means opening several documents instead of scrolling one. Only the untagged CHANGELOG.md tracks the current cycle, so anything older lives in a file whose name you have to infer from the date. The root also carries .git-blame-ignore-revs, a file that lists revisions excluded from blame output.
Editorial conclusion
Use Observable Plot when you want one small JavaScript dependency for exploratory charts built from marks and scales, and when you are willing to learn it from the documentation site rather than from the repository. Leave it alone if you need a frozen public API, or a component wrapper for a UI framework, and check which commit you actually install, because the registry version 0.6.17 predates the last push to main.
Frequently asked questions
What is an observable plot?
Observable Plot is a free, open-source JavaScript library for visualizing tabular data, published to npm as @observablehq/plot under an ISC license. Its API is built around scales and layered marks in the grammar of graphics style, and its stated focus is accelerating exploratory data analysis. The current version field in package.json reads 0.6.17.
What is the purpose of plotting data?
For this project the stated purpose is exploration. The description field calls it a JavaScript library for exploratory data visualization, and the README says the focus is accelerating exploratory data analysis of tabular data rather than producing fixed reports or dashboards.
What is the purpose of a plot diagram?
Diagrams here are assembled rather than selected from a menu of chart types. The description says the library implements a layered grammar of graphics, and the README links separate documentation pages for scales and for marks, which are the two concepts a chart is composed from.
What language does observable use?
Observable Plot itself is JavaScript. package.json sets type to module, points both main and module at src/index.js, ships type declarations from src/index.d.ts, and runs tsc as the second of four gates in the test script. The repository as a whole is tagged HTML, and it does carry a VitePress docs tree alongside src/ and test/.
Official sources
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.
[](https://hysenlabs.com/projects/observablehq-plot)Star history chart for your README
[](https://hysenlabs.com/projects/observablehq-plot)Was this useful?