dom-to-image, html-to-image, and html2canvas are browser-based libraries that convert DOM elements into image formats like PNG or JPEG by rendering HTML and CSS onto an HTML canvas. They enable client-side generation of visual snapshots of web content without requiring a server or headless browser. screenshot-desktop, in contrast, is a Node.js package that captures screenshots of the actual desktop or application windows using native operating system APIs—it does not render HTML and is unrelated to in-browser DOM manipulation. These tools serve fundamentally different purposes: the first three are for programmatic rendering of web content, while the last is for desktop automation and system-level screen capture.
Capturing visual representations of web content is a common need — from generating social media previews to creating PDF reports or saving user-designed layouts. The four packages under review solve overlapping but distinct problems in this space. Let’s break down their technical approaches, capabilities, and trade-offs.
dom-to-image, html-to-image, and html2canvas all convert DOM elements into raster images (PNG, JPEG, etc.) directly in the browser using JavaScript. They do not require a headless browser or external process.
screenshot-desktop, by contrast, captures screenshots of the entire desktop or specific windows — it runs only in Node.js and requires system-level access. It cannot render arbitrary HTML; it only snapshots what’s already visible on screen.
⚠️ Important:
screenshot-desktopis not a web content renderer. If your goal is to turn HTML/CSS into an image programmatically (e.g., for a chart, dashboard widget, or user-generated design),screenshot-desktopis not applicable.
All three browser-based libraries parse the DOM, apply computed styles, and draw the result onto an HTML <canvas>. However, their implementation strategies differ significantly.
html2canvas: Pixel-Perfect Simulation via Canvas Replayhtml2canvas attempts to replay the rendering process by walking the DOM tree, reading computed styles, and manually redrawing everything onto a canvas using the Canvas 2D API. It supports many CSS features (like border-radius, box-shadow, transforms) but has known limitations with complex layouts (e.g., flex, grid, clip-path).
// html2canvas: Basic usage
import html2canvas from 'html2canvas';
const element = document.getElementById('capture');
html2canvas(element).then(canvas => {
const imgData = canvas.toDataURL('image/png');
// Use imgData as needed
});
It offers fine-grained control via options like scale, useCORS, and logging:
html2canvas(element, {
scale: 2,
useCORS: true,
logging: false
}).then(canvas => { /* ... */ });
dom-to-image: SVG Serialization + Rasterizationdom-to-image takes a different approach: it serializes the target node to an inline SVG, embedding fonts and external resources as data URLs, then draws that SVG onto a canvas. This often yields better fidelity for vector-like content (text, icons, simple shapes) but struggles with advanced CSS effects that don’t translate cleanly to SVG.
// dom-to-image: Basic usage
import domtoimage from 'dom-to-image';
const node = document.getElementById('capture');
domtoimage.toPng(node)
.then(dataUrl => {
// Use dataUrl
})
.catch(error => console.error('Error:', error));
It provides multiple output formats (toPng, toJpeg, toSvg, toCanvas) and supports filtering nodes:
const filter = (node) => !(node instanceof HTMLIFrameElement);
domtoimage.toPng(node, { filter });
🔍 Note:
dom-to-imageappears to be unmaintained. Its npm page shows no recent updates, and the GitHub repo (tsayen/dom-to-image) has unresolved issues and open pull requests dating back years. Use with caution in new projects.
html-to-image: A Modern Fork of dom-to-imagehtml-to-image is a community-maintained fork of dom-to-image that addresses many bugs and adds new features (like better font handling, improved CORS support, and TypeScript definitions). It uses the same SVG serialization strategy but with active development and better reliability.
// html-to-image: Basic usage
import { toPng } from 'html-to-image';
const node = document.getElementById('capture');
toPng(node)
.then(dataUrl => {
// Use dataUrl
})
.catch(error => console.error('Error:', error));
It also supports custom styling overrides and pixel ratio control:
const options = {
pixelRatio: 2,
style: { margin: '0' }
};
toPng(node, options);
screenshot-desktop operates entirely outside the browser context. It leverages native OS APIs (via Node.js bindings) to capture screenshots. It’s useful for automated UI testing, desktop app monitoring, or capturing full-screen content — but not for rendering dynamic HTML.
// screenshot-desktop: Capture entire screen
import screenshot from 'screenshot-desktop';
screenshot().then(imgBuffer => {
// imgBuffer is a Buffer containing PNG data
});
// Or capture a specific window by title
screenshot({
screen: 0,
format: 'png',
filename: 'output.png'
});
Key limitations:
html2canvas: Supports images via useCORS: true but may fail with cross-origin fonts unless properly configured.dom-to-image: Embeds images/fonts as data URLs but often fails silently with CORS-protected assets.html-to-image: Improved CORS handling; can proxy external resources through a server if needed.screenshot-desktop: N/A — it captures pixels as displayed by the OS.html2canvas: Best for basic layout and styling. Struggles with modern CSS (e.g., backdrop-filter, complex gradients).dom-to-image / html-to-image: Better with text and vector graphics, but limited with CSS-only effects (shadows, blends).html2canvas: Can be slow on large/complex DOM trees due to deep traversal and canvas drawing.html-to-image: Generally faster than dom-to-image due to optimizations, but still blocks the main thread.screenshot-desktop: Very fast (native OS call), but irrelevant for in-browser rendering.html2canvashtml-to-imagedom-to-imagehtml-to-image instead.z-index handling).screenshot-desktopIf you’re currently using dom-to-image, migrating to html-to-image is straightforward:
// Before (dom-to-image)
import domtoimage from 'dom-to-image';
domtoimage.toPng(node);
// After (html-to-image)
import { toPng } from 'html-to-image';
toPng(node);
The API is nearly identical, but html-to-image exports individual functions instead of a single object.
| Package | Environment | Rendering Method | Actively Maintained? | Best For |
|---|---|---|---|---|
html2canvas | Browser | Canvas replay | ✅ Yes | General-purpose DOM capture with CSS support |
html-to-image | Browser | SVG serialization | ✅ Yes | Text/vector content; modern alternative |
dom-to-image | Browser | SVG serialization | ❌ No | Legacy projects only |
screenshot-desktop | Node.js | OS-level screenshot | ✅ Yes | Desktop automation, not web content rendering |
html-to-image for most new projects — it’s reliable, maintained, and handles common cases well.html2canvas if you’re dealing with complex CSS layouts that don’t translate well to SVG.dom-to-image in new codebases.screenshot-desktop only when you genuinely need to capture desktop pixels — never for rendering HTML programmatically.Choose html2canvas when you're capturing moderately complex UIs that rely on standard CSS layout and styling, and you need fine-grained control over the rendering process. It’s a solid choice if your content includes effects like shadows or borders that may not serialize well to SVG.
Choose html-to-image when you need a modern, actively maintained library for converting DOM elements to images in the browser, especially for content heavy in text, icons, or vector graphics. It handles fonts and external resources more reliably than older alternatives and offers good TypeScript support.
Avoid dom-to-image in new projects — it appears unmaintained, with unresolved bugs and no recent updates. If you're already using it and it works for your use case, consider migrating to html-to-image, which is a well-maintained fork with the same API but better reliability and active development.
Choose screenshot-desktop only when you need to capture actual desktop or application window screenshots from a Node.js environment—such as in desktop automation, UI testing of native apps, or system monitoring. It cannot render arbitrary HTML and should never be used for in-browser DOM-to-image conversion.
Homepage | Downloads | Questions
The script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
The script renders the current page as a canvas image, by reading the DOM and the different styles applied to the elements.
It does not require any rendering from the server, as the whole image is created on the client's browser. However, as it is heavily dependent on the browser, this library is not suitable to be used in nodejs. It doesn't magically circumvent any browser content policy restrictions either, so rendering cross-origin content will require a proxy to get the content to the same origin.
The script is still in a very experimental state, so I don't recommend using it in a production environment nor start building applications with it yet, as there will be still major changes made.
The library should work fine on the following browsers (with Promise polyfill):
As each CSS property needs to be manually built to be supported, there are a number of properties that are not yet supported.
The html2canvas library utilizes Promises and expects them to be available in the global context. If you wish to
support older browsers that do not natively support Promises, please include a polyfill such as
es6-promise before including html2canvas.
To render an element with html2canvas, simply call:
html2canvas(element[, options]);
The function returns a Promise containing the <canvas> element. Simply add a promise fulfillment handler to the promise using then:
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
You can download ready builds here.
Clone git repository:
$ git clone git://github.com/niklasvh/html2canvas.git
Install dependencies:
$ npm install
Build browser bundle
$ npm run build
For more information and examples, please visit the homepage or try the test console.
If you wish to contribute to the project, please send the pull requests to the develop branch. Before submitting any changes, try and test that the changes work with all the support browsers. If some CSS property isn't supported or is incomplete, please create appropriate tests for it as well before submitting any code changes.