const img = await snapdom.toPng(document.querySelector('#my-div'));. That's the entire recipe. The promise resolves to an HTMLImageElement you can append, download or upload.
Step 1: Install SnapDOM
npm install @zumer/snapdom
If you don't use a bundler, you can also use the CDN build:
<script type="module"> import { snapdom } from "https://unpkg.com/@zumer/snapdom/dist/snapdom.mjs"; </script>
Step 2: Pick the div you want to screenshot
Anything that's part of the live document tree works. Most people use document.querySelector:
const el = document.querySelector('#card');
The element doesn't need to be visible inside the viewport, but it does need to be attached to the document (not display: none).
Step 3: Capture it
One line:
import { snapdom } from '@zumer/snapdom'; const img = await snapdom.toPng(el);
The returned img is a real HTMLImageElement with the captured content as its src (a PNG data URL).
Step 4: Do something with the image
Append it to the page
const img = await snapdom.toPng(el); document.body.appendChild(img);
Download it as a file
const result = await snapdom(el); await result.download({ format: 'png', filename: 'card' });
Get a Blob to upload to a server
const blob = await snapdom.toBlob(el, { type: 'png' }); const form = new FormData(); form.append('file', blob, 'screenshot.png'); await fetch('/api/upload', { method: 'POST', body: form });
Full working example
Drop this into a fresh HTML file and open it in a browser:
<!DOCTYPE html> <html> <body> <div id="card" style="padding:24px;background:#6366f1;color:#fff;border-radius:12px;"> <h2>Hello SnapDOM</h2> <p>This entire div is about to become a PNG.</p> </div> <button id="go">Capture</button> <script type="module"> import { snapdom } from "https://unpkg.com/@zumer/snapdom/dist/snapdom.mjs"; document.getElementById('go').addEventListener('click', async () => { const img = await snapdom.toPng(document.getElementById('card')); document.body.appendChild(img); }); </script> </body> </html>
Or try it right here
The example above, running on this page: same div, same snapdom.toPng call:
Hello SnapDOM
This entire div is about to become a PNG.
Useful options
dpr: 2sets pixel density (auto-detectswindow.devicePixelRatiofor retina; override here when you need a fixed value).scale: 2multiplies the captured size (zoom). Different fromdpr:scalemakes the output bigger,dprmakes it sharper at the same logical size.backgroundColor: '#fff'fills transparent areas with a colour.embedFonts: trueinlines@font-facedeclarations so custom fonts render correctly.exclude: ['.skip']skips any element matching the selector.useProxy: 'https://your-proxy.example.com/'fetches cross-origin images through a CORS proxy.
Frequently asked questions
Why not use the browser's built-in screenshot API?
Ordinary JavaScript running inside a page has no built-in element-screenshot API. The Screen Capture API (getDisplayMedia) captures a tab or screen with user permission, not an arbitrary DOM element. Browser automation hosts do expose page and element screenshots; they can also inject SnapDOM when the output needs SVG, plugins or reusable exports.
Does this work with web fonts?
Yes, but you have to opt in. Pass { embedFonts: true } and SnapDOM will inline the matching @font-face declarations so the captured image renders with your real fonts.
Can I screenshot something inside an iframe?
Readable same-origin iframes are supported from the parent page. A sandboxed frame without allow-same-origin may still be opaque. A cross-origin parent cannot read the frame document, but an authorized Playwright or Puppeteer job can enter that frame context or open its URL separately and inject SnapDOM there. See the iframe guide.
What about Shadow DOM?
SnapDOM walks open Shadow DOM trees during capture, so Web Components render correctly.
How big is the library?
Around 50 KB minified and gzipped, with zero runtime dependencies.
Try the live demo
See SnapDOM running in your browser before installing it.
Open the demo Install from npm