# canvg: rendering SVG onto a Canvas from JavaScript or TypeScript

> canvg parses an SVG file or string and draws it into a canvas 2D context, which is what you want when you need pixels rather than an embedded image. The trade-off is that it implements a subset of the SVG spec, and the README says so.

**canvg/canvg** — JavaScript SVG parser and renderer on Canvas

- Repository: https://github.com/canvg/canvg
- Website: https://canvg.js.org
- Stars: 3,835 · Forks: 615
- Language: TypeScript
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/canvg-canvg

## The problem canvg solves: SVG that has to become pixels

An SVG in a page is usually an image element or an inline block of markup, and the browser handles painting. That breaks down the moment you need the rendered result as a bitmap. Exporting a chart to PNG, compositing an SVG logo onto a photo, or drawing vector artwork into a canvas that already holds other content are all cases where an image element is no help.

canvg takes the URL to an SVG file or the text of the SVG file, parses it in JavaScript, and renders the result on Canvas. That single sentence from the README describes both the input modes and the output target, and it also explains the audience. This is a library for people who are already working with a canvas 2D context and want SVG as one of the things they can draw into it.

The package description adds the second use case: rasterizing SVG images. Rasterizing means you want a buffer of pixels, not a live document. If you are generating a PNG on the server, or producing a thumbnail from an uploaded SVG, the parse-and-draw path is the whole point. If instead you just want an SVG displayed in a page, canvg is the wrong tool, and an image tag costs nothing.

## How canvg parses and draws: the Canvg object and its lifecycle

The architecture visible from the README is small. You import the Canvg class, construct an instance from a canvas 2D context plus either a URL or SVG text, and then call start on it. The instance is your handle on the rendering: the README's quickstart stores it in a variable and calls stop on it when the page unloads.

The constructor is asynchronous. In the example from the README, Canvg.from is awaited before v.start() runs, which fits an implementation that has to fetch the SVG when you pass a path. Passing the SVG text instead avoids that fetch, and the related searches show people looking for a fromString entry point, so string input is a path users ask about.

start is described in the README comment as starting SVG rendering with animations and mouse handling. That is a meaningful detail: canvg is not a one-shot rasterizer only. It keeps a live rendering loop and wires up pointer events, which is why stopping it matters. Leaving a started instance running after the canvas is gone is a leak the README implicitly warns about by showing v.stop() in onbeforeunload.

Nothing in the README describes a worker-based or offscreen pipeline, though the repository has a test/offscreen directory, so offscreen canvas support is exercised by tests rather than documented in the quickstart.

## Installing canvg and rendering your first SVG

The README gives three package manager commands and says to use your favorite. All three install the same package, and the package is ESM-first: package.json sets "type": "module" and the publish config exposes both a require entry (dist/index.cjs) and an import entry (dist/index.js).

```bash
pnpm add canvg
# or
yarn add canvg
# or
npm i canvg
```

After that, import the Canvg class and drive it from a canvas. This is the README's quickstart, unchanged. It expects a canvas element in the page and an SVG file at ./svgs/1.svg.

```js
import { Canvg } from 'canvg';

let v = null;

window.onload = async () => {
  const canvas = document.querySelector('canvas');
  const ctx = canvas.getContext('2d');

  v = await Canvg.from(ctx, './svgs/1.svg');

  // Start SVG rendering with animations and mouse handling.
  v.start();
};

window.onbeforeunload = () => {
  v.stop();
};
```

What you should see is the SVG drawn into the canvas rather than sitting in the DOM as a separate element, and if the file contains animation, it should keep moving until you call stop. The Node engine requirement in package.json is >=12.0.0, so a modern runtime is assumed. The README does not document a CDN build or a script-tag global in the quickstart, even though people search for those terms, so treat the module import as the supported path and check the website for anything else.

## Spec coverage is the real limitation, and the README admits it

The section headed What's implemented? is unusually honest. It states that the end goal is everything from the SVG spec, that the majority of the rendering and animation is working, and that feature requests should go to the issues list or, better, a pull request. Majority is not all. If your SVG leans on parts of the spec that are not implemented, the output will be wrong or incomplete and there is no compatibility table in the README to tell you which parts.

That is the failure mode to plan for. A filter that silently does nothing, a text layout that shifts, or an animation that stops early are all plausible outcomes when coverage is partial, and the README does not enumerate them. The practical check is the examples page and the demo, plus the test suite in the repository, which is split into test/util, test/canvg, test/browser, test/node and test/offscreen. Those directories tell you what the maintainers actually verify.

There is a second boundary: canvg renders onto canvas, so anything that depends on the SVG being live DOM (CSS from the surrounding page, script inside the SVG, accessibility semantics, text selection) is out of scope by construction. If those matter, an image element or inline SVG is the correct choice and canvg adds nothing.

## canvg compared with resvg-js and with a plain image element

The related searches pair canvg with resvg-js, and the difference in approach is worth stating plainly. canvg parses SVG in JavaScript and draws through the canvas 2D API, so it runs wherever a canvas context exists and inherits the browser's rasterizer. resvg-js is a different lineage: it wraps a Rust rendering library rather than drawing through canvas, which means it is not tied to a 2D context and can be used where no canvas exists, at the cost of a native or WASM dependency instead of a pure JavaScript one.

That distinction decides most cases. If your pipeline already produces a canvas and you want SVG to join it, canvg avoids a second rendering stack and works with the same context, including the animation and mouse handling the README describes. If you need rendering outside a canvas environment, or you want a renderer that does not depend on the host's canvas implementation, canvg is the wrong side of that line.

The comparison with a plain image element is simpler. An image element gives you the browser's own SVG renderer, full spec behaviour as the browser implements it, and no JavaScript bundle. What it does not give you is pixels you can read, composite and re-encode. canvg exists for that gap. If you never need the pixels, close the gap by not opening it.

## Maintenance, versioning and the MIT licence

The repository is not archived and the last push was on 2026-09-19, four days before this article's frame of reference, so recent activity is real rather than historical. The release history is more uneven: v4.0.3 and v3.0.11 both landed on 2025-03-13, and v4.0.2 dates to 2024-04-22. One release in a year, with a backport to the v3 line, suggests maintenance rather than a fast-moving project.

That matters for upgrade cost. The package.json version is 4.0.3, and the docs include a dedicated Migration to v4 page, which is the signal that the v3 to v4 jump is not a drop-in. Anyone running v3 should read that page before touching the dependency, and the existence of a v3.0.11 release alongside v4.0.3 means the older line still receives fixes, so upgrading is a choice rather than a forced move.

The licence is MIT, declared in package.json and shipped as a LICENSE file at the repository root. MIT is permissive: it allows commercial and closed-source use provided the copyright notice and permission notice are retained. That is a statement about the licence text, not legal advice; if your organisation has rules about attribution in distributed bundles, check them against the actual LICENSE file.

## Conclusion

Adopt canvg when you need SVG turned into canvas pixels inside JavaScript: rasterizing for export, drawing an SVG into an existing canvas pipeline, or animating an SVG with the built-in start and stop calls. Do not adopt it if you need the full SVG spec, since the README states the end goal is everything from the spec and that only the majority of rendering and animation works today, so check the specific elements and filters your artwork uses against the examples before committing. Verify first that your target runtime exposes a canvas 2D context (the repository ships separate node, browser and offscreen test suites, which tells you those are the environments the maintainers exercise), and read the migration to v4 page before upgrading anything written against v3, because the current package version is 4.0.3.

## FAQ

### Can I use SVG in Canva?

This question is about Canva, the design product, not about canvg. canvg is a JavaScript library that parses SVG and renders it onto a Canvas element; it has no relationship to Canva.

### Which is better, SVG or Canvas?

The two are not competing for the same job. An SVG in the page is painted by the browser; canvg renders SVG onto a canvas 2D context so you can read, composite or re-encode the pixels. If you do not need pixels, canvg adds nothing.

### How can I save an SVG file as a PNG file using JavaScript?

canvg renders SVG onto a canvas 2D context, so the PNG step is the canvas itself: draw with Canvg.from, then read the canvas back through its own export method. The README describes the library as able to rasterize SVG images, which is exactly this path.

## Sources

- [canvg/canvg on GitHub](https://github.com/canvg/canvg)
- [License: MIT](https://github.com/canvg/canvg/blob/master/LICENSE)
- [Project website](https://canvg.js.org)
- [README](https://github.com/canvg/canvg/blob/master/README.md)
- [Releases](https://github.com/canvg/canvg/releases)

---

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