SnapDOMGitHub★ 8K
Live demo

Live element

Hard parts

transform + shadow

Result

Nothing captured yet

Edit the title, then run. This uses the real library from unpkg.
Library Comparison

SnapDOM vs html-to-image

Two libraries built around the same SVG foreignObject approach — compared on fidelity, fonts, Shadow DOM, plugins and developer experience.

TL;DR

html-to-image and SnapDOM both clone the DOM and render it through SVG foreignObject. SnapDOM adds a plugin pipeline, capture reuse in v3, and options for fonts, exclusions and output sizing.

SnapDOM vs html-to-image, head to head

Both libraries export the same DOM element to PNG five times. Times are averaged, the faster one is highlighted. Run it on your machine — the gap is hardware- and content-dependent.

Test element to be captured by both libraries.
SnapDOM
Waiting to start…
html-to-image
Waiting to start…

A quick overview

html-to-image is a fork of dom-to-image with TypeScript support. Its image helpers return data URLs; it also provides Canvas and Blob exports.

SnapDOM exposes capture and export lifecycle hooks. Official plugins add portable HTML, structured context and maps, PDF images, GIF and video alongside filters, timestamps and text transformations. These plugins are separate from the core image and canvas exporters.

Feature matrix

FeatureSnapDOMhtml-to-image
Active maintenanceYesYes
Pseudo-elements (::before / ::after)SupportedYes
Web fonts (@font-face)Embedded; local font optionEmbedded
Shadow DOMOpen rootsOpen roots
CSS variablesYesYes
CSS counter() / counters()YesDepends on the case
Line-clamp / multi-line ellipsisYesDepends on the case
Plugin systemYes (official + custom)No
Output formatsSVG · PNG · JPG · WebP · Canvas · BlobSVG · PNG · JPG · Canvas · Blob
PDF exportPluginNo
TypeScript typesBundledBundled
LicenseMITMIT

Support varies by fixture and rendering mode; test your own UI. See the live benchmark for its pixel fixtures and loaded versions.

When to use which

Choose SnapDOM when…

  • You use Web Components or Shadow DOM heavily.
  • You need CSS counters or line-clamp ellipsis in the captured output.
  • You want to add filters, watermarks, ASCII or PDF export without forking the library.
  • You need fine-grained font control (embedFonts, localFonts, excludeFonts).

Check before migrating…

  • SnapDOM plugins extend the capture lifecycle; existing html-to-image post-processing needs adapting.
  • Compare open Shadow DOM, CSS counters and line-clamp on the components you ship.
  • html-to-image has font embedding controls and canvas-based encoding; compare option semantics before mapping them.

Same task, side by side

Capturing #card as a PNG and inserting the resulting image into the page:

html-to-image

import { toPng } from 'html-to-image';

const dataUrl = await toPng(document.querySelector('#card'));
const img = new Image();
img.src = dataUrl;
document.body.appendChild(img);

SnapDOM

import { snapdom } from '@zumer/snapdom';

const img = await snapdom.toPng(document.querySelector('#card'));
document.body.appendChild(img);

Migration snippet

html-to-imageSnapDOM
toPng(el)(await snapdom.toPng(el)).src
toJpeg(el, { quality: 0.9 })(await snapdom.toJpg(el, { quality: 0.9 })).src
toBlob(el)snapdom.toBlob(el, { format: 'png' })
toCanvas(el)snapdom.toCanvas(el)
toSvg(el)snapdom.toRaw(el)
{ backgroundColor: '#fff' }{ backgroundColor: '#fff' }
{ pixelRatio: 2 }{ dpr: 2 }
{ filter: keep }{ exclude: node => !keep(node) }
{ fontEmbedCSS }No direct equivalent; embedFonts: 'auto' discovers used fonts
— (not supported){ plugins: [...] }
// Before
import { toPng } from 'html-to-image';
const dataUrl = await toPng(el, { pixelRatio: 2 });

// After
import { snapdom } from '@zumer/snapdom';
const img = await snapdom.toPng(el, { dpr: 2 });

Frequently asked questions

What's actually different between html-to-image and SnapDOM?

Both clone the DOM and render via foreignObject. SnapDOM adds capture lifecycle hooks, automatic reuse for eligible repeat captures, and official plugins for HTML, structured context and maps, PDF images, GIF and video. Compare the return types and options in the migration table.

Does SnapDOM render web fonts better than html-to-image?

Both libraries can embed @font-face declarations. SnapDOM v3.x.x defaults to embedFonts: 'auto' for used web fonts and also supports localFonts and excludeFonts. Check the exported text with your actual font files and browser.

Can I add a watermark or filter without forking the library?

Yes — that's exactly what the SnapDOM plugin system is for. Use the colorTint, filter or timestampOverlay plugins, or write your own with two callbacks (afterClone / beforeExport). Browse the plugins page for the full list.

How do I export to PDF?

Use the MIT pdf plugin. Its toPdf() method returns a PDF Blob with selectable text, pagination and links. The plugin is available on npm in @zumer/snapdom-plugins 4.x; see the PDF reference for installation and examples.

Ready to try SnapDOM?

Try the capture and export methods on an element from your project.

Open the demo Installation