In less than two months, Snapdom reached 2,120+ stars, with 7 contributors and a growing user base. But the goal has been clear since day one:
Build a modern, accurate and fast replacement for
html2canvas.
Why a replacement?
html2canvas was a milestone. I love it. It brought DOM-to-image to mainstream frontend. But time has passed, and the web platform has evolved: higher DPI screens, complex shadows, pseudo-elements with ::before { content: url(...) }, imported icon fonts, variables inside gradients, shadow DOM, web components, and more.
Many of those features don’t render correctly in html2canvas. Snapdom aims to fix that with a new approach.
What Snapdom does differently
Snapdom captures how a DOM looks. While tools like html2canvas attempt to reproduce the layout procedurally using canvas drawing commands, Snapdom takes a different route:
- It builds a visual clone of the DOM using a serialized structure and renders it via SVG with <foreignObject>.
- Styles are computed via getComputedStyle()and inlined per element, or collapsed into reusable CSS classes whencompressmode is enabled.
- Snapdom uses caching strategies for computed styles, fonts, and DOM shape to improve render performance.
- It supports hi-DPI scaling, fixed size snapshots, and consistent box models across browsers.
This approach makes it fast, modular, and portable — and allows Snapdom to produce SVG output that can be rendered, embedded, or exported in almost any format.
Visual fidelity
- Captures ::before/::after/::first-letter, including icons, URLs and inline content.
- Supports background-imagewith multiple layers:url(),linear-gradient(...),var(...), mixed.
- Handles shadows, filters, transforms, blend modes, scroll, overflow, and z-index correctly.
- Captures shadow DOM content and visual order.
Fonts and icon support
- Full support for @font-facevia stylesheets orFontFace()constructor.
- Correct rendering of icon fonts (FontAwesome, Material Icons, etc.) — including inside pseudo-elements.
- 
embedFonts: truewill inline all fonts into the SVG.
DOM state
- Captures current values of inputs, selects, and textareas.
- Preserves scroll position (scrollTop,scrollLeft).
- HiDPI / Retina support via devicePixelRatio.
- Optional fixed dimensions with widthand/orheight.
await snapdom(el, {
  width: 1024,
  height: 768,
  embedFonts: true,
  compress: true,
});
Performance-focused
- Snapshots in milliseconds, even on complex pages.
- One-time capture → multiple exports:
const result = await snapdom(el);
await result.toSvg();
await result.toPng();
await result.toWebp({ backgroundColor: "#fff" });
Coming soon: Plugin system
We're working on a native plugin architecture so anyone can extend Snapdom with custom needs.
Some ideas:
- Watermarking
- PDF export
- WebGL / canvas integration
- Post-capture mutation (blurring, tinting, overlays, etc.)
- Integration with visual editors
The plugin API will allow users to hook into preprocessing, postprocessing, and export logic.
API at a glance
const result = await snapdom(el, {
  scale: 2,
  compress: true,
  embedFonts: true,
  backgroundColor: "#fff",
  crossOrigin: "anonymous",
});
// Exports
await result.toSvg();
await result.toCanvas();
await result.toPng();
await result.toWebp();
await result.toImg();
- 
data-capture="exclude"skips a node and its children.
- 
data-capture="placeholder"replaces a node with an empty box (useful for ads, iframes, etc).
Try it
📦 GitHub → github.com/zumerlab/snapdom
🧪 Live demo → zumerlab.github.io/snapdom
Snapdom is fully browser-based. No canvas hacks, no server dependency. Just clean JS + SVG + Web APIs.
We're actively looking for feedback and contributors. If you're hitting limits with
html2canvas, try Snapdom and help shape its future.
 


 
    
Top comments (0)