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:
- DOM capture libraries (SnapDOM, html2canvas, html-to-image, dom-to-image, modern-screenshot) execute inside a real browser page. That can be the user's existing page, with no server round trip, or a page opened from Node.
- Browser automation (Puppeteer, Playwright) launches or connects to a controlled browser and owns navigation, authentication and page state. Use its native screenshot for direct pixels, or inject SnapDOM for SVG, plugins and reusable exports.
- Hosted APIs (HCTI, Urlbox, and similar) let you send HTML and get a rendered image back. Zero infra, real Chromium fidelity, but a paid per-render cost and a network hop.
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
| Library | Approach | Shadow DOM | Web fonts | Pseudo-elements | Speed (large DOM) | Maintained | No browser worker |
|---|---|---|---|---|---|---|---|
| SnapDOM | foreignObject | Yes | Yes | Yes | Fast | Active | Yes |
| html2canvas | JS re-paint | No | Partial | Partial | Slow | 1.4.1 (2022) | Yes |
| html-to-image | foreignObject | Partial | Yes | Yes | Fast | Active | Yes |
| modern-screenshot | foreignObject | Partial | Yes | Yes | Fast | Active | Yes |
| dom-to-image | foreignObject | No | Partial | Partial | Medium | Unmaintained | Yes |
| Puppeteer / Playwright | Browser control | Yes | Yes | Yes | Browser start | Active | No — 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
SnapDOM vs html2canvas
The classic DOM-to-canvas library vs the modern foreignObject approach. Pseudo-elements, fonts, plugins and speed.
Maintained forkSnapDOM vs html-to-image
The popular dom-to-image fork compared head-to-head with SnapDOM on fidelity, fonts and Shadow DOM.
LegacySnapDOM 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 peerSnapDOM vs modern-screenshot
Same foreignObject approach, TypeScript-first. Where SnapDOM's plugins and broader fidelity net make the difference.
IntegrationSnapDOM with Puppeteer
Let Puppeteer control the browser, then choose native pixels or inject SnapDOM for SVG, plugins and reusable exports.
IntegrationSnapDOM 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
- Need open Shadow DOM, lifecycle hooks or plugin-defined exports? Choose SnapDOM.
- Already on html2canvas with font / Shadow DOM bugs → migrate to SnapDOM (familiar
toPng/toJpg/toBlobAPI; usually a one-line swap). - Need a small client-side dependency? SnapDOM is about 50 KB gzip with no runtime dependencies; plugins are separate imports.
- Still on dom-to-image → upgrade; it's unmaintained.
- Need server-generated output? Use Puppeteer / Playwright or a hosted browser service; inject SnapDOM when its SVG, plugin or multi-export pipeline is useful.
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