Vega-Embed

Embed interactive Vega and Vega-Lite visualizations into any web page with a single function call.

Library
npm
v7.1.0
499stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
69/100Good
Development Activity64
Maintenance48
Community84
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture80
Code Quality72
Innovation85
Learning Curve85

Vega-Embed is a small JavaScript/TypeScript library from the Vega project that turns a Vega or Vega-Lite specification into an interactive, embedded visualization on any web page. It handles rendering, packages in Vega Tooltip and Vega Themes, and adds optional action links for viewing source, exporting PNG/SVG, and opening the chart in the online Vega Editor.

It ships as both an ES module for bundler-based apps and a UMD build for direct <script> tag use (via CDNs like jsDelivr), making it the standard glue layer between a Vega/Vega-Lite spec and a rendered chart in the DOM — used heavily in tools like Observable notebooks and documentation sites across the data-visualization ecosystem.

What You Get

  • A single embed()/vegaEmbed() entry point that renders Vega or Vega-Lite specs into a DOM element or CSS selector and resolves to a Promise with the live View, spec, compiled Vega spec, and a finalize() cleanup method.
  • Built-in Vega Tooltip and Vega Themes integration, plus a config-driven action menu for exporting PNG/SVG, viewing the source spec/compiled Vega, and opening the chart in the hosted Vega Editor.
  • Dual build output — an ES module for bundler-based apps (import embed from 'vega-embed') and a UMD bundle for direct <script> tag use via CDNs like jsDelivr/unpkg.
  • A container() helper purpose-built for Observable notebooks, returning a value-bearing HTML element instead of a bare Promise.
  • Support for patching specs at runtime via a function, JSON-Patch (RFC6902) document, or URL, letting you tweak a Vega-Lite-compiled spec before it renders.

Common Use Cases

  • Embedding interactive charts and dashboards on documentation sites, blogs, and marketing pages from a Vega-Lite JSON spec.
  • Powering chart cells in Observable notebooks via the container() API.
  • Adding export-to-PNG/SVG and ‘view source’ affordances to publicly shared data visualizations.
  • Loading and rendering third-party or server-generated Vega/Vega-Lite specs by URL without a build step, via the CDN script-tag path.

Under The Hood

Architectureindex.ts exports a polymorphic default function that inspects its arguments (element vs. spec, arg count) and dispatches to either embed() (src/embed.ts) or the Observable-oriented container() (src/container.ts). embed.ts is the core: it resolves the spec (string URL vs. parsed object), infers mode (vega or vega-lite) by parsing the spec’s $schema field, compiles Vega-Lite specs down to Vega specs via vega-lite’s compile(), optionally applies a runtime patch (function, JSON-Patch via fast-json-patch, or a fetched URL), merges themes (vega-themes) and config through mergeDeep (src/util.ts, built on Vega’s own writeConfig), instantiates a vega.View, wires up a Vega Tooltip Handler, renders into the target element, and appends an action-link menu whose “open in Vega Editor” option round-trips the spec to the external editor via post.ts’s postMessage handshake.

Tech Stack — TypeScript (~71% of the codebase), bundled by Rollup (rollup.config.js) into two artifacts: an ESM build (build/embed.js, the package’s exports.default) and a terser-minified UMD build (build/vega-embed.min.js, referenced by the unpkg/jsdelivr fields) via @rollup/plugin-typescript, -node-resolve, -commonjs, and -json. vega and vega-lite are peer dependencies ("*", left for the consumer to pin); direct dependencies are small utilities (fast-json-patch, json-stringify-pretty-compact, semver, tslib, vega-interpreter, vega-schema-url-parser) plus pinned vega-themes/vega-tooltip versions. Component styling is compiled separately from vega-embed.scss into src/style.ts by build-style.sh (Sass) ahead of the Rollup build. Tests run on Vitest with jsdom and vitest-canvas-mock; linting uses ESLint’s flat config with typescript-eslint and Prettier; releases are cut with release-it and conventional-changelog.

Code Quality — The test/ directory has 48 tests across three files (embed.test.ts ~42, container.test.ts 4, util.test.ts 2), covering renderer switching, action-menu rendering, custom Vega expression functions, and spec patching — solid coverage of the public surface for a ~550-line core module, though edge cases around the postMessage editor handshake and error paths are thin. Source files stay small and single-purpose (util.ts 20 lines, types.ts 16, post.ts 33, container.ts 29), keeping complexity low per file. TypeScript types (EmbedOptions, Actions, Hover, Mode) are used consistently across the public API for compile-time safety. Error handling largely relies on native Promise rejection propagating up from Vega’s View rather than custom wrapping, and post.ts uses a hardcoded 10-second polling timeout for the editor handshake rather than an explicit failure/reject path.

API Designembed(el, spec, opt) needs only two required arguments and ships permissive defaults (DEFAULT_ACTIONS enables the full action menu), auto-detecting vega vs. vega-lite mode from the spec’s $schema so callers rarely set mode explicitly. The polymorphic default export in index.ts (choosing between embed and container based on argument shape) trades a bit of predictability for zero-friction use in Observable notebooks — an unusual but clearly documented pattern. The options object is large (30+ fields) but every field is optional and documented in a README table, and getting started requires nothing beyond embed('#vis', spec). Action-menu labels are overridable via an i18n option, and TypeScript consumers get full autocompletion on EmbedOptions/VisualizationSpec.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search