# SVG.js: a dependency-free library for building and animating SVG in the browser

> SVG.js gives you a small JavaScript API for creating, querying and animating SVG elements without pulling in a framework. It suits teams that generate vector graphics at runtime and want direct control over the DOM nodes underneath.

**svgdotjs/svg.js** — The lightweight library for manipulating and animating SVG

- Repository: https://github.com/svgdotjs/svg.js
- Website: https://svgjs.dev
- Stars: 11,826 · Forks: 1,077
- Language: JavaScript
- License: NOASSERTION
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/svgdotjs-svg-js

## What SVG.js actually solves for a JavaScript team

The browser's native SVG API is verbose. Creating a single rectangle means calling document.createElementNS with the SVG namespace, setting attributes one at a time, and appending the node. SVG.js wraps that into a chainable object model: you create a drawing surface, then call methods that return elements you can keep working on. The README describes it as "a lightweight library for manipulating and animating SVG, without any dependencies", and the package.json confirms there are no runtime dependencies listed.

That matters most when SVG is generated at runtime rather than authored by hand. Dashboards that redraw shapes from live data, editors that let users drag and resize nodes, and diagram tools that build connectors dynamically all end up writing the same createElementNS boilerplate. SVG.js replaces it with a queryable, chainable API that also carries an animation layer and a typed interface. It is not a charting library and it does not decide what you draw. It gives you the drawing primitives and the event plumbing, and leaves layout and data mapping to you.

## The object model behind the chainable API

The library exposes a single entry point that creates an SVG root and returns a container object. From that container you add shapes, groups, text and paths, and each call returns the new element so you can chain attributes and transforms. Elements are addressed by CSS selectors through a find method, which means you can query a subtree the same way you would query HTML. The repository ships a hand-written declaration file, svg.js.d.ts, and the package.json points its types field at it, so TypeScript consumers get completions on the same methods the JavaScript API offers.

Animation is part of the same model rather than a separate module. Elements carry methods that interpolate attributes over a duration, and the animation runs against the DOM node the element wraps. Because every wrapper maps to a real SVG node, anything the library does not expose can still be reached through the underlying element. That escape hatch is worth knowing about, because it is how you handle attributes the API has not wrapped.

Build output is split by environment. The exports map routes a browser bundler to dist/svg.esm.js, a CommonJS require to dist/svg.node.cjs, and exposes dist/svg.min.js through the unpkg and jsdelivr fields for script-tag use. There is no separate runtime to load.

## Installing SVG.js from npm and drawing a first shape

The README gives npm and Yarn as the two package-manager routes, plus three CDNs. The npm package name is scoped, so the install command is not simply svg.js. The README gives this example:

```bash
npm install @svgdotjs/svg.js
```

The README does not include a usage snippet; it points readers to svgjs.dev for the API itself. So the first real step after installing is to open the documentation site linked from the README and follow the examples there, rather than copying a snippet from the repository's front page. What the package.json does tell you is which file your build will load: a browser bundler resolves to dist/svg.esm.js, a CommonJS require resolves to dist/svg.node.cjs, and a script tag can load dist/svg.min.js from unpkg or jsdelivr, since both fields point at that file.

If you prefer a script tag, the README lists cdnjs, jsdelivr and unpkg as the three CDN hosts. Loading dist/svg.min.js from one of them exposes the same API globally, with no module loader involved.

## Where SVG.js stops being the right tool

SVG.js is a manipulation layer, not a rendering engine. It does not compute layouts, it does not manage a scene graph with retained state across frames, and it does not give you a physics or timeline system. If your requirement is a chart with axes, scales and tooltips, you are looking at a different category of library and would be rebuilding that layer on top of SVG.js.

The animation API is also attribute interpolation, not a general-purpose timeline. Sequencing many coordinated animations, or synchronising SVG motion with video, means writing the coordination yourself. And because the library writes directly to DOM nodes, a virtual-DOM framework that also owns those nodes will fight it for control. The README does not document a React binding, so integration with React means managing the SVG root in a ref and keeping the library's mutations out of React's reconciliation.

Finally, the licence metadata is inconsistent across the sources: the README states SVG.js is licensed under the MIT License, and the package.json lists "license": "MIT", while the repository is tagged with a NOASSERTION licence identifier. Treat that as something to confirm against LICENSE.txt in the repository rather than assuming either label is authoritative.

## SVG.js versus D3 and Snap.svg

D3 and SVG.js both write SVG into the DOM, but they start from opposite ends. D3 is built around data joins: you bind an array to a selection, and the library computes enter, update and exit sets so the DOM follows the data. SVG.js has no data-join concept. You create elements imperatively and keep references to them. For a chart whose shape is driven by a dataset, D3's model removes a whole class of bookkeeping. For an editor where users add and move individual shapes, D3's join machinery is overhead you do not need.

Snap.svg is the closer comparison, since it also wraps SVG creation and animation in a chainable API. The practical difference visible in the packaging is this: SVG.js publishes as a scoped npm package with an exports map covering browser, import and require conditions, ships dist/svg.min.js for CDN use, and includes svg.js.d.ts for TypeScript. The README also states there are no dependencies, which keeps the install footprint to the library itself.

Neither comparison is a verdict. Pick D3 when the data drives the geometry, and SVG.js when the geometry is the thing you are editing.

## Release cadence, licence and the cost of upgrading

The release history shows long gaps between versions. 3.2.4 landed on 2024-06-27, 3.2.5 on 2025-09-15, and 3.2.6 on 2026-07-17. The last push to the repository was on 2026-08-04, and the repository is not archived. The package.json in the tree declares version 3.2.8, ahead of the most recent tagged release listed, so the published line and the working tree are not at the same point.

That pattern has a practical consequence: a team adopting SVG.js should expect to sit on a minor version for a year or more, and should read CHANGELOG.md before jumping. The repository keeps one at the top level. Because the API is chainable and element-oriented, upgrades mostly mean checking that methods you call still exist and that the declaration file still types them.

The licence question is the one to settle before shipping. The README and package.json both say MIT, which permits commercial use and modification with attribution, but the repository's licence identifier reads NOASSERTION, meaning the hosting platform did not recognise the file it found. Read LICENSE.txt and, if the discrepancy matters to your legal team, raise it upstream. This is a description of what the files say, not legal advice.

## TypeScript, module formats and other integration details

The package is published as an ES module ("type": "module") with a conditional exports map. A bundler that understands the browser condition gets dist/svg.esm.js. A CommonJS consumer falls back to dist/svg.node.cjs. Node's default resolution for the package root lands on the ESM build. If you hit an unexpected module format in a test runner, the exports map is the first place to look, because the choice is made by the consumer's conditions rather than by a single main field.

TypeScript users get types from svg.js.d.ts, referenced both by the exports entry and by the top-level typings field. That file is hand-maintained alongside the source, so a method added to the runtime may lag in the typings. If a documented method does not autocomplete, checking the declaration file against the documentation site is faster than assuming the method is missing.

The repository also carries a bench directory, a spec directory, and playgrounds, which tells you the maintainers keep performance measurements and runnable examples in-tree. Those are useful when you want to see intended usage rather than inferred usage.

## Conclusion

Adopt SVG.js when you need programmatic control over SVG elements, animations and DOM events in a plain JavaScript or TypeScript project, and you want zero runtime dependencies. Skip it if you need a charting layer, a full graphics engine with filters and gradients beyond what the API exposes, or a React-native component model, since the library manipulates the DOM directly. Before committing, verify the version you install against the 3.2.x line, check that the svg.js.d.ts typings cover the methods you plan to call, and confirm the module format your bundler picks up from the exports map.

## FAQ

### What is SVG.js?

SVG.js is a JavaScript library for manipulating and animating SVG, described in its README as lightweight and free of dependencies. It is published on npm as @svgdotjs/svg.js and documented at svgjs.dev.

### How do I add SVG.js to a project?

The README gives npm install @svgdotjs/svg.js and yarn add @svgdotjs/svg.js, plus cdnjs, jsdelivr and unpkg for script-tag use. The package.json maps the unpkg and jsdelivr fields to dist/svg.min.js.

### How does SVG.js compare with D3?

D3 is built around data joins that compute enter, update and exit sets from a bound array, while SVG.js has no data-join concept and expects you to create elements imperatively and hold references to them. Choose based on whether the data or the individual shape is what you are editing.

### How does SVG.js compare with Snap.svg?

Both wrap SVG creation and animation in a chainable API. The difference visible in the packaging is that SVG.js publishes with an exports map covering browser, import and require conditions, ships a minified CDN build, and includes svg.js.d.ts for TypeScript.

### What are alternatives to SVG.js?

D3 and Snap.svg both manipulate SVG in the browser but differ in approach: D3 centres on data joins, and Snap.svg offers a comparable chainable wrapper. SVG.js distinguishes itself by having no dependencies and shipping TypeScript declarations.

## Sources

- [Issues](https://github.com/svgdotjs/svg.js/issues)
- [Project website](https://svgjs.dev)
- [README](https://github.com/svgdotjs/svg.js/blob/master/README.md)
- [Releases](https://github.com/svgdotjs/svg.js/releases)
- [svgdotjs/svg.js on GitHub](https://github.com/svgdotjs/svg.js)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/svgdotjs-svg-js
