Snapdom: a modern and faster alternative to html2canvas



This content originally appeared on DEV Community and was authored by Juan Martin

In less than two months, Snapdom reached 2,120+ stars, with 7 contributors and a growing user base. But the goal has been clear since day one:

Build a modern, accurate and fast replacement for html2canvas.

Why a replacement?

html2canvas was a milestone. I love it. It brought DOM-to-image to mainstream frontend. But time has passed, and the web platform has evolved: higher DPI screens, complex shadows, pseudo-elements with ::before { content: url(...) }, imported icon fonts, variables inside gradients, shadow DOM, web components, and more.

Many of those features don’t render correctly in html2canvas. Snapdom aims to fix that with a new approach.

Benchmark

What Snapdom does differently

Snapdom captures how a DOM looks. While tools like html2canvas attempt to reproduce the layout procedurally using canvas drawing commands, Snapdom takes a different route:

  • It builds a visual clone of the DOM using a serialized structure and renders it via SVG with <foreignObject>.
  • Styles are computed via getComputedStyle() and inlined per element, or collapsed into reusable CSS classes when compress mode is enabled.
  • Snapdom uses caching strategies for computed styles, fonts, and DOM shape to improve render performance.
  • It supports hi-DPI scaling, fixed size snapshots, and consistent box models across browsers.

This approach makes it fast, modular, and portable — and allows Snapdom to produce SVG output that can be rendered, embedded, or exported in almost any format.

Visual fidelity

  • Captures ::before / ::after / ::first-letter, including icons, URLs and inline content.
  • Supports background-image with multiple layers: url(), linear-gradient(...), var(...), mixed.
  • Handles shadows, filters, transforms, blend modes, scroll, overflow, and z-index correctly.
  • Captures shadow DOM content and visual order.

Fonts and icon support

  • Full support for @font-face via stylesheets or FontFace() constructor.
  • Correct rendering of icon fonts (FontAwesome, Material Icons, etc.) — including inside pseudo-elements.
  • embedFonts: true will inline all fonts into the SVG.

DOM state

  • Captures current values of inputs, selects, and textareas.
  • Preserves scroll position (scrollTop, scrollLeft).
  • HiDPI / Retina support via devicePixelRatio.
  • Optional fixed dimensions with width and/or height.
await snapdom(el, {
  width: 1024,
  height: 768,
  embedFonts: true,
  compress: true,
});

Performance-focused

  • Snapshots in milliseconds, even on complex pages.
  • One-time capture → multiple exports:
const result = await snapdom(el);
await result.toSvg();
await result.toPng();
await result.toWebp({ backgroundColor: "#fff" });

Coming soon: Plugin system

We’re working on a native plugin architecture so anyone can extend Snapdom with custom needs.

Some ideas:

  • Watermarking
  • PDF export
  • WebGL / canvas integration
  • Post-capture mutation (blurring, tinting, overlays, etc.)
  • Integration with visual editors

The plugin API will allow users to hook into preprocessing, postprocessing, and export logic.

API at a glance

const result = await snapdom(el, {
  scale: 2,
  compress: true,
  embedFonts: true,
  backgroundColor: "#fff",
  crossOrigin: "anonymous",
});

// Exports
await result.toSvg();
await result.toCanvas();
await result.toPng();
await result.toWebp();
await result.toImg();
  • data-capture="exclude" skips a node and its children.
  • data-capture="placeholder" replaces a node with an empty box (useful for ads, iframes, etc).

Try it

📦 GitHub → github.com/zumerlab/snapdom
🧪 Live demo → zumerlab.github.io/snapdom

Snapdom is fully browser-based. No canvas hacks, no server dependency. Just clean JS + SVG + Web APIs.

We’re actively looking for feedback and contributors. If you’re hitting limits with html2canvas, try Snapdom and help shape its future.


This content originally appeared on DEV Community and was authored by Juan Martin