English | 简体中文
SnapDOM is a next-generation DOM Capture Engine — the fast, modern alternative to html2canvas, dom-to-image, and html-to-image.
It converts any DOM subtree into a self-contained representation that can be exported to SVG, PNG, JPG, WebP, Canvas, Blob, or any custom format through plugins — ultra-fast, modular, extensible, and dependency-free.
Full DOM capture with embedded styles, pseudo-elements and fonts; export to SVG, PNG, JPG, WebP, canvas or Blob — ultra fast, dependency-free, and 100% based on standard Web APIs.
👉 See the complete technical feature list in FEATURES.md.
Capture any DOM element to PNG in one line:
import { snapdom } from '@zumer/snapdom';
const img = await snapdom.toPng(document.querySelector('#card'));
document.body.appendChild(img);Reusable capture (one clone, multiple exports):
const result = await snapdom(document.querySelector('#card'));
await result.toPng(); // → HTMLImageElement
await result.toSvg(); // → SVG as Image
await result.download({ format: 'jpg', filename: 'card.jpg' });- Quick Start
- Features
- Installation
- Build Outputs
- Usage
- Documentation — full API, Options, Plugins & Cache reference on snapdom.dev/docs
- Limitations
- Performance Benchmarks
- Development
- Contributors
- Sponsors
- License
npm i @zumer/snapdom
yarn add @zumer/snapdomFor early access to new features and fixes:
npm i @zumer/snapdom@dev
yarn add @zumer/snapdom@dev@dev tag usually includes improvements before they reach production, but may be less stable.
<!-- Minified build -->
<script src="https://unpkg.com/@zumer/snapdom/dist/snapdom.js"></script>
<!-- Minified ES Module build -->
<script type="module">
import { snapdom } from "https://unpkg.com/@zumer/snapdom/dist/snapdom.mjs";
</script><!-- Minified build (dev) -->
<script src="https://unpkg.com/@zumer/snapdom@dev/dist/snapdom.js"></script>
<!-- Minified ES Module build (dev) -->
<script type="module">
import { snapdom } from "https://unpkg.com/@zumer/snapdom@dev/dist/snapdom.mjs";
</script>| Variant | File | Use case |
|---|---|---|
| ESM (tree-shakeable) | dist/snapdom.mjs |
Bundlers (Vite, webpack), import |
| IIFE (global) | dist/snapdom.js |
Script tag, legacy require |
Bundler (npm):
import { snapdom } from '@zumer/snapdom'; // → dist/snapdom.mjsScript tag (CDN):
<script src="https://unpkg.com/@zumer/snapdom/dist/snapdom.js"></script>
<script> snapdom.toPng(document.body).then(img => document.body.appendChild(img)); </script>Subpath imports (lighter bundle if you only need one):
import { preCache } from '@zumer/snapdom/preCache';
import { plugins } from '@zumer/snapdom/plugins';| Pattern | When to use |
|---|---|
Reusable snapdom(el) |
One clone → many exports (PNG + JPG + download). |
Shortcuts snapdom.toPng(el) |
Single export, less code. |
Capture once, export many times (no re-clone):
const el = document.querySelector('#target');
const result = await snapdom(el);
const img = await result.toPng();
document.body.appendChild(img);
await result.download({ format: 'jpg', filename: 'my-capture.jpg' });Direct export when you need a single format:
const png = await snapdom.toPng(el);
const blob = await snapdom.toBlob(el);
document.body.appendChild(png);The full reference lives on snapdom.dev/docs — kept there so it stays in sync and searchable:
- API reference — the
snapdom()reusable object, shortcut methods, and exporter-specific options. - Options — every capture option (
scale,dpr,embedFonts,useProxy,exclude/filter,compress,outerTransforms,outerShadows,cache…) explained with examples. - Plugins — build, register and ship custom plugins and export formats. Browse community plugins on the plugins page.
- Cache & preCache — control caching between captures and preload resources.
snapdom(el, options?) returns a reusable object (toPng, toSvg, toCanvas, toBlob, toJpg, toWebp, download, url). For single exports, use the shortcuts:
| Method | Description |
|---|---|
snapdom.toSvg(el, options?) |
Returns an SVG HTMLImageElement |
snapdom.toCanvas(el, options?) |
Returns a Canvas |
snapdom.toBlob(el, options?) |
Returns an SVG or raster Blob |
snapdom.toPng(el, options?) |
Returns a PNG image |
snapdom.toJpg(el, options?) |
Returns a JPG image |
snapdom.toWebp(el, options?) |
Returns a WebP image |
snapdom.download(el, options?) |
Triggers a download |
📖 Full API & every option → snapdom.dev/docs
- External images should be CORS-accessible (use
useProxyoption for handling CORS denied) - When WebP format is used on Safari, it will fallback to PNG rendering.
@font-faceCSS rule is well supported, but if need to use JSFontFace(), see this workaround#43- Safari: captures with
embedFontsor background/mask images run slower due to WebKit #219770 (font decode timing). SnapDOM does pre-captures +drawImageto prime the pipeline; configurable viasafariWarmupAttempts(default 3). - Custom scrollbar styles (
::-webkit-scrollbar): Applied only when the element has not been scrolled. When scrolled, the viewport content is captured without the scrollbar.
Setup. Vitest benchmarks on Chromium, repo tests. Hardware may affect results. Values are average capture time (ms) → lower is better.
| Scenario | SnapDOM current | SnapDOM v1.9.9 | html2canvas | html-to-image |
|---|---|---|---|---|
| Small (200×100) | 0.5 ms | 0.8 ms | 67.7 ms | 3.1 ms |
| Modal (400×300) | 0.5 ms | 0.8 ms | 75.5 ms | 3.6 ms |
| Page View (1200×800) | 0.5 ms | 0.8 ms | 114.2 ms | 3.3 ms |
| Large Scroll (2000×1500) | 0.5 ms | 0.8 ms | 186.3 ms | 3.2 ms |
| Very Large (4000×2000) | 0.5 ms | 0.9 ms | 425.9 ms | 3.3 ms |
| Scenario | SnapDOM current | SnapDOM v1.9.9 | html2canvas | html-to-image |
|---|---|---|---|---|
| Small (200×100) | 1.6 ms | 3.3 ms | 68.0 ms | 14.3 ms |
| Modal (400×300) | 2.9 ms | 6.8 ms | 87.5 ms | 34.8 ms |
| Page View (1200×800) | 17.5 ms | 50.2 ms | 178.0 ms | 429.0 ms |
| Large Scroll (2000×1500) | 54.0 ms | 201.8 ms | 735.2 ms | 984.2 ms |
| Very Large (4000×2000) | 171.4 ms | 453.7 ms | 1,800.4 ms | 2,611.9 ms |
git clone https://github.com/zumerlab/snapdom.git
cd snapdom
npm install
npm run test:benchmarkSource layout:
src/api/– Public API (snapdom,preCache)src/core/– Capture pipeline, clone, prepare, pluginssrc/modules/– Images, fonts, pseudo-elements, backgrounds, SVGsrc/exporters/– toPng, toSvg, toBlob, etc.dist/– Build output (snapdom.js,snapdom.mjs,preCache.mjs,plugins.mjs)
Build:
git clone https://github.com/zumerlab/snapdom.git
cd snapdom
git checkout dev
npm install
npm run compileTest:
npx playwright install # Required for browser tests
npm test
npm run test:benchmarkFor detailed guidelines, see CONTRIBUTING.
Special thanks to @megaphonecolin, @sdraper69, @reynaldichernando, @gamma-app, @jrjohnson, and @ryanander for supporting this project!
If you'd like to support this project too, you can become a sponsor.
MIT © Zumerlab