Both libraries render cloned DOM through foreignObject and export SVG, PNG, JPEG, WebP, Canvas and Blob. modern-screenshot has a TypeScript API. SnapDOM also provides a plugin system for HTML, structured context and maps, PDF images, GIF and video. Both are MIT-licensed.
SnapDOM vs modern-screenshot, 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.
Same approach, different scope
modern-screenshot and SnapDOM belong to the same family as html-to-image: instead of re-implementing the CSS painter the way html2canvas does, they deep-clone the DOM, inline styles/fonts/images, and wrap the clone in an SVG <foreignObject> so the browser performs the actual render. The shared rendering approach does not guarantee identical output or timing; test the content and browsers you use.
The core output formats overlap. SnapDOM exposes an extensible capture and export lifecycle, with official plugins for additional representations and transformations. Both libraries have browser-specific rendering behavior to check on complex pages.
Feature matrix
| Feature | SnapDOM | modern-screenshot |
|---|---|---|
| Rendering approach | Clone + foreignObject | Clone + foreignObject |
| Output formats | SVG · PNG · JPG · WebP · Canvas · Blob | PNG · JPEG · WebP · SVG · Canvas · Blob |
| Plugin system | Yes | No |
Web fonts (@font-face) | Embedded | Yes |
| Pseudo-elements | Yes | Yes |
| Shadow DOM | Open roots | Open roots |
| TypeScript-first API | Typed, JS core | Yes |
| Runtime dependencies | 0 | 0 |
| Maintained | Active | Active |
| License | MIT | MIT |
Feature support in other libraries evolves — for anything version-specific, check their docs for the latest. Or run the live benchmark above and compare the output yourself.
When to use which
Choose SnapDOM when…
- You want to extend capture with plugins (watermarks, filters, custom exporters, PDF…).
- Your UI uses Shadow DOM / Web Components and you need them captured reliably.
- You hit edge cases (Safari rendering, complex
@font-face, counters, line-clamp) and want them already handled. - You want one API spanning SVG, PNG, JPG, WebP, Canvas and Blob.
Check your existing workflow…
- Decide whether post-processing or capture lifecycle hooks suit your transformations.
- Test your Web Components in the browsers you support.
- Compare Safari output and complex
@font-facesetups with your assets. - Core image formats overlap; optional SnapDOM plugins add HTML, context, PDF and animation exports.
Same task, side by side
Capturing #card as a PNG and inserting the resulting image into the page:
modern-screenshot
import { domToPng } from 'modern-screenshot'; const dataUrl = await domToPng(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);
modern-screenshot's domToPng resolves to a data-URL string; SnapDOM's toPng resolves to a ready-to-append HTMLImageElement. For a PNG data URL, read (await snapdom.toPng(el)).src. snapdom.toRaw(el) returns an SVG data URL.
Migration map
Check the format and return type at each call site. SnapDOM image helpers return HTMLImageElement; read .src for a data URL. Its default Blob format is SVG, so request PNG explicitly when migrating a PNG Blob export.
| modern-screenshot | SnapDOM |
|---|---|
| domToPng(node) | (await snapdom.toPng(node)).src |
| domToJpeg(node) | (await snapdom.toJpg(node)).src |
| domToWebp(node) | (await snapdom.toWebp(node)).src |
| domToSvg(node) | snapdom.toRaw(node) |
| domToCanvas(node) | snapdom.toCanvas(node) |
| domToBlob(node) | snapdom.toBlob(node, { format: 'png' }) |
Frequently asked questions
Is SnapDOM or modern-screenshot faster?
Timing depends on the element, assets, browser and whether the capture is fresh or repeated. Use the live benchmark with its displayed library versions, then test both libraries on your own content.
What does SnapDOM offer that modern-screenshot doesn't?
SnapDOM has a plugin lifecycle and official plugins for portable HTML, structured context and maps, PDF images, GIF and video. The two libraries share the core SVG, raster image, Canvas and Blob output formats.
Can I migrate from modern-screenshot without rewriting everything?
Common exports have equivalents, but return types and options need review. For a PNG string use (await snapdom.toPng(el)).src; snapdom.toRaw(el) returns SVG. Request format: 'png' when a Blob consumer expects PNG.
Are both libraries free for commercial use?
Yes. SnapDOM and modern-screenshot are MIT-licensed. Neither library charges a per-capture fee or requires a screenshot server.
Try SnapDOM on your page
Capture a rendered element as PNG, SVG or Canvas. Add other exports through plugins.
Open the demo Installation