dom-to-image-more is a maintained fork of the original dom-to-image library that converts an arbitrary DOM node into a PNG, JPEG, or SVG image entirely in the browser, and it exists because the original stopped getting the bug fixes people needed. If you've ever built a "download this chart as an image" or "share this receipt" feature, you've hit the problem dom-to-image-more solves: the browser has no native "screenshot this element" API, so you have to reconstruct the node as an image yourself. The fork carries forward the original dom to image approach — serialize the node into an SVG <foreignObject>, then rasterize it via a canvas — while merging fixes the upstream project left sitting.
How it works under the hood
The mechanism is a clever use of SVG. An SVG <foreignObject> element can contain arbitrary HTML. dom-to-image-more clones your target node, inlines its computed styles and any web fonts, wraps the result in a <foreignObject> inside an SVG, and sets that SVG as the source of an image. Drawing that image onto a canvas gives you pixels you can export as a data URL. The top-level API returns promises:
import domtoimage from 'dom-to-image-more';
const node = document.getElementById('chart');
domtoimage.toPng(node)
.then((dataUrl) => {
const img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
});
toJpeg, toSvg, and toBlob follow the same pattern. The fork ships its own TypeScript definitions, so you don't need a separate @types install, and the types cover fork-specific options.
What the fork improves
The reason to prefer dom-to-image-more over the original is a longer list of merged fixes and features:
- Better handling of same-origin and blob iframes, which the original struggled with.
- Web font and image embedding fixes so exported images don't lose fonts.
- Options the original lacks, including style caching for performance, CORS image handling (
corsImg,useCredentials), request timeouts (httpTimeout), and hooks likeadjustClonedNodeandrequestInterceptorfor customizing the clone.
That last set is why the fork wins in real apps: rendering fidelity depends on getting cross-origin images and fonts embedded correctly, and the extra options give you the control to do it.
The security considerations
Here's where a rendering library earns a security guide. dom-to-image-more works by cloning and re-rendering DOM — so whatever is in that DOM gets rendered. Two things to keep in mind:
Rendering user-controlled content. If the node you capture contains user-supplied HTML, the same cross-site scripting (XSS) concerns that apply to displaying that HTML apply here too. The library isn't a sanitizer; it faithfully reproduces what's there. Sanitize user content before it enters the DOM (with a library like DOMPurify), not at capture time. The threat isn't unique to this library — it's the general rule that untrusted HTML must be sanitized before it reaches the page.
Cross-origin resource loading. The corsImg and useCredentials options control whether the library sends credentials when fetching images to embed. Sending credentials to third-party image hosts can leak session cookies; only enable credentialed requests for origins you control, and set a sane httpTimeout so a slow external resource can't hang the export.
Supply-chain hygiene. The fork is one of several competing forks of dom-to-image (there are packages named dom-to-image-more, html-to-image, and others). Confirm you're installing the one you intend, pin the version in your lockfile, and scan it. An SCA scanner such as Safeguard will flag any known advisory in the package or its dependencies, which matters given how many near-identically-named forks exist in this corner of npm.
Choosing between the forks
If you're starting fresh, html-to-image is another actively maintained option built on the same <foreignObject> technique and is worth comparing. dom-to-image-more is the natural pick when you're already on the original dom-to-image API and want a drop-in upgrade with the accumulated fixes. Either way, avoid the unmaintained original dom-to-image package for new work — it's the same abandonment pattern that bites any frozen dependency, covered further in the Academy.
Practical tips
Capture at the right pixel ratio for crisp output on high-DPI screens by passing a scale or setting explicit dimensions. Wait for fonts and images to finish loading before you call toPng, or the export will race and miss assets. And render off-screen rather than flashing the node visibly if the capture is purely for download. These are ergonomics, but they're the difference between a feature that works in the demo and one that works for every user's content.
FAQ
What is the difference between dom-to-image and dom-to-image-more?
dom-to-image-more is a fork of the original dom-to-image with a large number of merged bug fixes and added features — better iframe handling, web font and image embedding fixes, CORS options, and its own TypeScript types. The original is effectively unmaintained, so the fork is the safer choice.
Is dom-to-image-more a security risk?
The library itself renders DOM faithfully; the risk comes from what you feed it. If you capture user-supplied HTML, sanitize it before it enters the DOM to prevent XSS, and be careful with credentialed cross-origin image requests. Scan the package like any dependency.
Do I need @types for dom-to-image-more?
No. The package ships its own TypeScript definitions covering the standard API and the fork-specific options, so a separate @types install isn't required.
Can dom-to-image-more capture cross-origin images?
Yes, with care. It offers options like corsImg and useCredentials to control how cross-origin images are fetched and embedded. Only enable credentialed requests for origins you trust, since sending credentials to third-party hosts can leak session data.