Library Comparisons
zumerlab/snapdom

Best HTML-to-Image JavaScript Library

An honest, code-level comparison of the libraries that turn a DOM element into an image — html2canvas, html-to-image, dom-to-image, modern-screenshot and snapDOM. Feature matrix, the trade-offs behind each approach, and how to actually pick one.

Last updated: June 2026 · maintained by the snapDOM team.

Three ways to turn HTML into an image

Every tool here solves the same problem — "render this DOM node to a PNG/JPG/SVG" — but they fall into three families, and the right pick depends almost entirely on which family fits your constraints:

The rest of this page focuses on the client-side libraries, because that's where most projects start and where the differences are subtle.

Feature matrix

LibraryApproachShadow DOMWeb fontsPseudo-elementsSpeed (large DOM)MaintainedNo server
snapDOMforeignObjectYesYesYesFastActiveYes
html2canvasJS re-paintNoPartialPartialSlow1.4.1 (2022)Yes
html-to-imageforeignObjectPartialYesYesFastActiveYes
modern-screenshotforeignObjectPartialYesYesFastActiveYes
dom-to-imageforeignObjectNoPartialPartialMediumUnmaintainedYes
Puppeteer / PlaywrightReal ChromiumYesYesYesSlow startActiveServer

"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.

The libraries, reviewed

snapDOM

Best for new browser-side projects that need real CSS fidelity. snapDOM clones the DOM and lets the browser render it inside an SVG <foreignObject>, so anything the browser paints, it captures — pseudo-elements, CSS variables, transforms, counters, open Shadow DOM and embedded web fonts included. It's zero-dependency, ships a plugin system, and outputs SVG, PNG, JPG, WebP, Canvas or Blob. Honest limit: like every client-side tool it's browser-only — it can't capture cross-origin tainted canvases without a proxy, and it isn't a substitute for server Chromium when you need byte-identical output across engines.

html2canvas

The incumbent — but aging. html2canvas re-implements the CSS painter in JavaScript and walks only the light DOM, so Shadow DOM trees render empty and web fonts frequently fall back to system fonts. It's slow on dense trees because every node is repainted in JS. The last stable release (1.4.1) shipped in January 2022, the repo carries 1,000+ open issues, and the README still calls it experimental. If you're hitting font or layout bugs with it, that's the signal to migrate.

html-to-image

The lightweight pick for simple cards. html-to-image is a maintained fork of dom-to-image using the same foreignObject technique. It's small, fast and good enough for marketing cards, badges and forms. It handles fonts well; Shadow DOM and some edge-case CSS are where snapDOM pulls ahead. A sensible default when bundle size matters more than completeness.

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; the practical differences come down to fidelity edge cases, plugin extensibility and output formats. Worth a look if you want something minimal and modern.

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 you need byte-perfect cross-browser output, PDF export at scale, or rendering that can't depend on the user's browser, Puppeteer / Playwright (self-hosted) or a hosted API (HCTI, Urlbox) are the right tools — at the cost of running a headless browser or paying per render. They're complementary to, not competitors of, a client-side library.

Which should you use?

FAQ

What is the best HTML-to-image library in 2026?

For client-side use, snapDOM offers the most complete CSS fidelity (Shadow DOM, pseudo-elements, web fonts) with active maintenance; html-to-image and modern-screenshot are strong lightweight alternatives. For server-side pixel-perfect rendering, use Puppeteer/Playwright or a hosted API.

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 — every client-side library on this page runs entirely in the browser. You only need a server (Puppeteer/Playwright) or a hosted API when you require byte-identical cross-engine output or PDF generation at scale.

Try snapDOM in 30 seconds

Capture any DOM element to PNG with a single import. No build step, no dependencies.

Open the demo View on GitHub