SnapDOMGitHub8K
Library Comparisons
zumerlab/snapdom

HTML-to-image libraries compared

Compare html2canvas, html-to-image, dom-to-image, modern-screenshot and SnapDOM by rendering approach, supported DOM features, maintenance and execution model.

Last updated: August 2026 · maintained by the SnapDOM team.

Three layers you can use separately or together

These tools do not all occupy the same layer. A DOM capture library can run inside a page controlled by browser automation, so the server/client distinction is not an either-or choice:

The matrix compares DOM capture libraries and includes Playwright and Puppeteer as a browser-automation reference. Their guides show how the automation and capture layers compose.

Feature matrix

LibraryApproachShadow DOMWeb fontsPseudo-elementsSpeed (large DOM)MaintainedNo browser worker
SnapDOMforeignObjectYesYesYesFastActiveYes
html2canvasJS re-paintNoPartialPartialSlow1.4.1 (2022)Yes
html-to-imageforeignObjectPartialYesYesFastActiveYes
modern-screenshotforeignObjectPartialYesYesFastActiveYes
dom-to-imageforeignObjectNoPartialPartialMediumUnmaintainedYes
Puppeteer / PlaywrightBrowser controlYesYesYesBrowser startActiveNo — browser process

"Partial" means it works for common cases but has documented gaps. The matrix is a summary. Read the head-to-head deep dives below for the specifics that matter to your codebase.

Head-to-head deep dives

Most popular

SnapDOM vs html2canvas

The classic DOM-to-canvas library vs the modern foreignObject approach. Pseudo-elements, fonts, plugins and speed.

Maintained fork

SnapDOM vs html-to-image

The popular dom-to-image fork compared head-to-head with SnapDOM on fidelity, fonts and Shadow DOM.

Legacy

SnapDOM vs dom-to-image

An old favourite that hasn't shipped in years. See what you gain by switching to a maintained, plugin-based engine.

Modern peer

SnapDOM vs modern-screenshot

Same foreignObject approach, TypeScript-first. Where SnapDOM's plugins and broader fidelity net make the difference.

Integration

SnapDOM with Puppeteer

Let Puppeteer control the browser, then choose native pixels or inject SnapDOM for SVG, plugins and reusable exports.

Integration

SnapDOM with Playwright

Keep Playwright's navigation and test lifecycle while running SnapDOM inside the selected browser page.

The libraries, reviewed

SnapDOM

For DOM capture with broad CSS coverage. SnapDOM clones the DOM and lets the browser render it inside an SVG <foreignObject>. It handles pseudo-elements, CSS variables, transforms, counters, open Shadow DOM and embedded web fonts. It has no runtime dependencies, supports plugins and exports SVG, PNG, JPG, WebP, Canvas or Blob. It does not navigate or launch a browser and cannot bypass cross-origin access from the current page context. Pair it with Puppeteer or Playwright when a server must own the browser lifecycle.

html2canvas

A JavaScript CSS renderer with a large installed base. html2canvas reads the DOM and implements supported CSS painting itself. That gives it a different compatibility profile from foreignObject-based libraries. Its latest stable release is 1.4.1 from January 2022; the project README still describes it as experimental and lists unsupported CSS as an inherent limitation.

html-to-image

A maintained fork of dom-to-image. html-to-image uses the same foreignObject technique and has a compact API. SnapDOM adds open Shadow DOM capture, a plugin lifecycle and more built-in export paths.

modern-screenshot

The closest architectural cousin. modern-screenshot is a newer, actively maintained, TypeScript-first foreignObject library, fast and clean. It overlaps heavily with SnapDOM in approach; in practice the choice comes down to SnapDOM's plugin pipeline, broader output formats and fidelity edge-case coverage.

dom-to-image

Avoid for new projects. dom-to-image is the original foreignObject library and the ancestor of html-to-image, but it's effectively unmaintained and struggles with modern flexbox/grid layouts. If you're on it today, html-to-image or SnapDOM are direct, low-friction upgrades.

Server-side & hosted options

When rendering cannot depend on the user's browser, use Puppeteer or Playwright to run a pinned browser build with controlled viewport, fonts, locale and device scale, or use a hosted API. Take a native screenshot for one bitmap. Inject SnapDOM into that page when the server also needs SVG, plugin processing, several formats from one capture or the same export path as the client app. Reproducibility comes from fixing the environment; different browser engines are not expected to produce byte-identical files.

Choose by execution model

FAQ

Which HTML-to-image library should I use?

Use SnapDOM when a real browser page contains the DOM and you need open Shadow DOM, web fonts, pseudo-elements or plugin-defined formats. For a user-triggered export, run it in that user's page. For server-generated output, let Puppeteer or Playwright control a pinned browser and either take a native screenshot or inject SnapDOM into the loaded page.

Is there a maintained html2canvas alternative?

Yes. SnapDOM, html-to-image and modern-screenshot are all actively maintained and use the faster foreignObject approach instead of html2canvas's JavaScript re-paint. SnapDOM additionally supports Shadow DOM and a plugin system.

Why does my capture miss web fonts or Shadow DOM?

That's usually html2canvas or dom-to-image: they don't reliably embed @font-face or traverse Shadow roots. Libraries that render via foreignObject (SnapDOM, html-to-image, modern-screenshot) let the browser paint the real result, so fonts and shadow content are captured.

Can I convert HTML to an image without a server?

Yes. Run a DOM capture library in the user's existing browser and no screenshot server is required. If the backend must generate the artifact, it needs a controlled browser or hosted browser API; SnapDOM can be injected into that page rather than replaced.

Test SnapDOM on a real element

Open the demo or install the package and compare the result on your own DOM.

Open the demo View on GitHub