Voltar ao ranking

zumerlab/snapdom

JavaScriptsnapdom.dev

High-performance engine for capturing, modifying, and converting DOM elements into any format.

screenshotdomclonecapture-screendom-manipulationfidelityjavascriptplugin-systemsnapdom-plugin
Crescimento de estrelas
Estrelas
8k
Forks
294
Crescimento semanal
Issues
3
2k4k6k
set. de 25dez. de 25abr. de 26jul. de 26
Artefatosnpmnpm install snapdom
README

Website NPM version NPM weekly downloads GitHub contributors GitHub stars GitHub forks Sponsor tinchox5 License

English | 简体中文

SnapDOM

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.

📖 Documentation, guides & live demos → snapdom.dev

Features

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.

Website & Live Demos

https://snapdom.dev

Quick Start

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' });

Table of Contents

Installation

NPM / Yarn (stable)

npm i @zumer/snapdom
yarn add @zumer/snapdom

NPM / Yarn (dev builds)

For early access to new features and fixes:

npm i @zumer/snapdom@dev
yarn add @zumer/snapdom@dev

⚠️ The @dev tag usually includes improvements before they reach production, but may be less stable.

CDN (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>

CDN (dev builds)

<!-- 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>

Build Outputs

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

Script 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';

Usage

Pattern When to use
Reusable snapdom(el) One clone → many exports (PNG + JPG + download).
Shortcuts snapdom.toPng(el) Single export, less code.

Reusable capture

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' });

One-step shortcuts

Direct export when you need a single format:

const png = await snapdom.toPng(el);
const blob = await snapdom.toBlob(el);
document.body.appendChild(png);

Documentation

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.

API at a glance

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

Options at a glance

All options are optional and can be passed to snapdom(el, options) or any shortcut method.

Option Type Default Description
scale number 1 Output scale multiplier
dpr number devicePixelRatio Pixel density of the rasterized output
width / height number null Target output size (keeps aspect ratio if only one is set)
backgroundColor string null (#ffffff for JPEG/WebP) Background fill
quality number 0.92 JPEG/WebP quality (0–1)
format 'png' | 'jpeg' | 'webp' | 'svg' 'png' Format for download()
type string 'svg' Blob type for toBlob() ('png', 'jpeg'…)
filename string 'snapDOM' Download filename
embedFonts boolean false Inline @font-face so text renders with your real fonts
iconFonts string | RegExp | array [] Icon font families (always embedded)
localFonts array [] Explicit fonts: { family, src, weight?, style? }
excludeFonts object Skip fonts by family / domain / subset
exclude string[] [] CSS selectors to leave out of the capture
filter (el) => boolean null Keep-predicate (return false to drop a node)
excludeMode / filterMode 'hide' | 'remove' 'hide' How excluded nodes are handled
clip 'viewport' | {x, y, width, height} null Capture only a region; offscreen content is pruned
compress boolean true Downsample inlined images to their visible resolution
useProxy string '' CORS proxy prefix for cross-origin images
fallbackURL string | fn Fallback image for broken <img>
cache 'soft' | 'auto' | 'full' | 'disabled' 'soft' Cache policy between captures
outerTransforms boolean true Keep root translate/rotate in the output
outerShadows boolean false Expand bounds to include root shadows/blur/outline
fast boolean true Skip idle delays for faster capture
plugins array Per-capture plugins (override globals by name)

📖 Full API & every option, explained with examples → snapdom.dev/docs

Limitations

  • External images should be CORS-accessible (use useProxy option for handling CORS denied)
  • When WebP format is used on Safari, it will fallback to PNG rendering.
  • @font-face CSS rule is well supported, but if need to use JS FontFace(), see this workaround #43
  • Safari: captures with embedFonts or background/mask images run slower due to WebKit #219770 (font decode timing). SnapDOM does pre-captures + drawImage to prime the pipeline; configurable via safariWarmupAttempts (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.

Performance Benchmarks

Setup. Vitest benchmarks on Chromium, repo tests. Hardware may affect results. Values are average capture time (ms) → lower is better.

Simple elements

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

Complex elements

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

Run the benchmarks

git clone https://github.com/zumerlab/snapdom.git
cd snapdom
npm install
npm run test:benchmark

Development

Source layout:

  • src/api/ – Public API (snapdom, preCache)
  • src/core/ – Capture pipeline, clone, prepare, plugins
  • src/modules/ – Images, fonts, pseudo-elements, backgrounds, SVG
  • src/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 compile

Test:

npx playwright install   # Required for browser tests
npm test
npm run test:benchmark

For detailed guidelines, see CONTRIBUTING.

Contributors

tinchox5 pdufour FlavioLimaMindera Jarvis2018 tarwin Amyuan23 kohaiy airamhr9 jswhisperer K1ender mosuzi 17biubiu av01d CHOYSEN pedrocateexte claude domialex elliots stypr mon-jai puneetdixit200 RinZ27 sharuzzaman simon1uo titoBouzout ZiuChen adajoy harshasiddartha

Sponsors

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.

Show your support

If SnapDOM saved you time, a ⭐ on GitHub helps other developers find it — that's the whole ask.

Shipping something built with SnapDOM? Add the badge to your README:

Built with SnapDOM

[![Built with SnapDOM](https://img.shields.io/badge/built%20with-SnapDOM-blue)](https://snapdom.dev)

Projects using SnapDOM

SnapDOM runs in production across 290+ public repositories (GitHub dependents graph). A few notable ones, each verified from its own package.json:

See the full gallery at snapdom.dev/made-with. Shipping SnapDOM? Open a PR to add your project — real, verifiable projects only.

License

MIT © Zumerlab

Repositórios relacionados
hiroi-sora/Umi-OCR

OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。

PythonPyPIMIT Licensepaddleocrocr
46.2k4.5k
ShareX/ShareX

ShareX is a free and open-source application that enables users to capture or record any area of their screen with a single keystroke. It also supports uploading images, text, and various file types to a wide range of destinations.

C#GNU General Public License v3.0screen-capturescreen-recorder
getsharex.com
38.7k3.9k
jaywcjlove/linux-command

Linux命令大全搜索工具,内容包含Linux命令手册、详解、学习、搜集。https://git.io/linux

MarkdownMIT Licenselinuxlinux-command
jaywcjlove.github.io/linux-command
36.4k6.6k
niklasvh/html2canvas

Screenshots with JavaScript

TypeScriptnpmMIT Licensejavascriptscreenshot
html2canvas.hertzen.com
31.9k4.9k
flameshot-org/flameshot

Powerful yet simple to use screenshot software :desktop_computer: :camera_flash:

C++GNU General Public License v3.0screenshotqt
flameshot.org
30.4k2k
xiaojieonly/Ehviewer_CN_SXJ

ehviewer,用爱发电,快乐前行

COtherscreenshotehviewer
25.5k669
dylanaraps/neofetch

🖼️ A command-line system information tool written in bash 3.2+

ShellMIT Licensecommandlinecommand-line
23.7k1.8k
zsh-users/zsh-syntax-highlighting

Fish shell like syntax highlighting for Zsh.

ShellBSD 3-Clause "New" or "Revised" Licenseshellsyntax-highlighting
github.com/zsh-users/zsh-syntax-highlighting
22.9k1.4k
gildas-lormeau/SingleFile

Web Extension for saving a faithful copy of a complete web page in a single HTML file

JavaScriptnpmGNU Affero General Public License v3.0browserarchive
getsinglefile.com
21.9k1.4k
CapSoftware/Cap

Open source Loom alternative. Beautiful, shareable screen recordings.

TypeScriptnpmOtherappcap
cap.so
20.3k1.7k
MathewSachin/Captura

Capture Screen, Audio, Cursor, Mouse Clicks and Keystrokes

C#MIT Licensecapturescreenshot
mathewsachin.github.io/Captura/
10.8k2k
bubkoo/html-to-image

✂️ Generates an image from a DOM node using HTML5 canvas and SVG.

TypeScriptnpmMIT Licensescreenshotcanvas
7.2k674