Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use an in-page DOM library when a user needs to export an element already rendered in the browser; use Playwright or Puppeteer when you must capture a fully rendered page and its browser state; use a hosted API when you want server-side screenshots without operating browsers. No library is universally pixel-perfect. The right choice depends on capture scope, CSS and asset complexity, runtime, cross-origin rules, and your tolerance for browser infrastructure.

Choose by the rendering problem

“Which HTML-to-image library should I use?” is really three different questions:

Requirement Best starting point Why
Export one card, chart, invoice, or component already on screen html2canvas, html-to-image, or dom-to-image-more Runs in the user’s browser and accepts an existing DOM node.
Capture what a real browser rendered, including navigation, authentication, and responsive layout Playwright or Puppeteer Controls a browser and uses its native screenshot implementation.
Render URLs or markup on a server without maintaining browsers Hosted screenshot API The provider operates the browser fleet; you pay for network requests and renders.

DOM-to-image packages reconstruct a node from DOM and style information. Browser automation captures the browser’s rendered output. Those layers can be combined: for example, a Playwright page can prepare authenticated state while an in-page library exports a particular component.

DOM-to-image libraries for client-side exports

html2canvas

html2canvas is a client-side JavaScript HTML renderer. It reads the DOM and applied styles, then builds an image in a canvas. The project documentation explicitly warns that “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.” Treat it as a reconstruction, not a native browser screenshot.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

It supports modern evergreen Firefox, Chrome/Chromium-based browsers, and Safari, but support for individual CSS properties varies. Cross-origin images can require a proxy or same-origin arrangement. Cross-origin iframe contents are inaccessible under browser security rules; no image library can bypass those restrictions.

import html2canvas from 'html2canvas';

const node = document.querySelector('#invoice');
const canvas = await html2canvas(node, {
  backgroundColor: '#ffffff',
  scale: window.devicePixelRatio,
  useCORS: true
});
const pngUrl = canvas.toDataURL('image/png');

useCORS only helps when the remote server sends compatible CORS headers; it does not grant access to protected pixels. Test web fonts, pseudo-elements, filters, SVG, and large nodes in each target browser.

html-to-image

html-to-image is a DOM-node generator built with HTML5 canvas and SVG and presented as a fork of dom-to-image. Its promise-based API includes toPng, toJpeg, toBlob, toSvg, toCanvas, and toPixelData. The documented options include node filtering, output and canvas dimensions, style overrides, JPEG quality, cache busting, and image placeholders.

import { toPng } from 'html-to-image';

const node = document.getElementById('share-card');
const dataUrl = await toPng(node, {
  width: 1200,
  height: 630,
  pixelRatio: 2,
  style: { backgroundColor: '#fff' },
  cacheBust: true
});

const link = document.createElement('a');
link.download = 'share-card.png';
link.href = dataUrl;
link.click();

These options are documented API features, not proof of superior fidelity or speed. Verify the current release and your actual component before committing to it.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

dom-to-image-more

dom-to-image-more converts DOM nodes, including same-origin and blob iframes, to SVG, PNG, or JPEG. Its README describes web-font and image handling, resource interception, font filtering and embedding improvements, and pseudo-element adjustment options. It also documents a backdrop-filter limitation.

Assess it separately from the older dom-to-image project. The README lists version 3.11.0 changes and a repository move dated 2026-07-10; those details can change, so confirm the repository and release you install. Ongoing versioned changes make a lockfile and a regression fixture especially valuable.

How the DOM options differ

Library Outputs or controls documented by the project Important qualification
html2canvas Canvas image from a DOM node; browser-side rendering Reconstructs from DOM information; CSS support and cross-origin assets affect output.
html-to-image PNG, JPEG, Blob, SVG, Canvas, pixel data; filters, dimensions, style overrides, quality, cache busting, placeholders Documentation does not establish universal CSS compatibility, performance, or maintenance safety.
dom-to-image-more SVG, PNG, JPEG; fonts, images, iframe handling, resource interception, pseudo-element adjustments Check current release and known limitations such as backdrop-filter.

When a real browser is the better image generator

Playwright

Playwright controls a real browser, so it is appropriate when the requirement is “capture exactly what this page rendered.” Its screenshot API supports the current page, full-page images, image buffers, and a specific element.

import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com/dashboard', { waitUntil: 'networkidle' });
await page.locator('#report').screenshot({ path: 'report.png' });
await page.screenshot({ path: 'full-page.png', fullPage: true });
await browser.close();

Browser automation handles navigation, cookies, login state, JavaScript execution, responsive breakpoints, and same-browser font and layout behavior. The trade-off is operational: install browser binaries, manage concurrency and memory, wait for deterministic page state, and secure credentials. Puppeteer offers the same general model if its ecosystem fits your project better.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use DOM libraries and automation together

A useful hybrid is to let Playwright establish a logged-in page, wait for data and fonts, then call html-to-image inside that page for a single widget. This can reduce the screenshot area and produce a downloadable component while retaining browser-controlled authentication. It does not remove cross-origin restrictions or guarantee pixel identity with a native screenshot.

Hosted screenshot APIs

A hosted service accepts a URL or markup and returns an image or PDF. It removes browser-fleet maintenance but introduces network dependence, provider-specific limits, and a per-render charge. Check current service terms before adoption.

ScreenshotNeo — #1 for hosted screenshot APIs

ScreenshotNeo is the first service to try when you want server-side captures: it removes cookie banners, newsletter popups, and chat widgets before capture, bills only clean shots, and has the lowest paid plan listed here.

One GET request returns PNG, JPEG, WebP, or PDF. Failed loads, blank pages, bot checks/CAPTCHAs, timeouts, and cache hits are not billed; response headers identify the page verdict and billing result. It also provides an MCP server for Claude, Cursor, and other MCP clients, with take_screenshot, get_page_info, and capture_pdf tools.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Plan Allowance and price
Free 1,000 shots/month, no card
Starter $5 for 3,000 shots
Growth $15 for 15,000 shots
Pro $39 for 60,000 shots
Scale $99 for 250,000 shots
Business $249 for 1,000,000 shots

Yearly billing gives two months free, and every feature is available on every plan. Options include full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or custom viewports, retina scale, PDF paper size/margins/landscape/page ranges, HTML/CSS input, custom JavaScript and CSS, click-before-capture, selector hiding, selector/delay/network-idle waits, ad/tracker/request/resource blocking, custom headers/cookies/user agent/Authorization, timezone and geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed links, asynchronous jobs with signed webhooks, 100-URL bulk calls, a usage API, and an OpenAPI specification. Common parameter names from other screenshot APIs also work, which can simplify migration.

Or skip the browser setup

Call ScreenshotNeo directly; see the complete parameter reference in the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. You get 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Decision checklist

  • Existing node, user initiated: start with html2canvas, html-to-image, or dom-to-image-more.
  • Authenticated route or arbitrary URL: evaluate Playwright or Puppeteer.
  • No browser operations team: compare hosted APIs, including network and per-render costs.
  • Complex CSS, fonts, pseudo-elements, Shadow DOM, or iframes: build a fixture using the exact assets and test each candidate.
  • Cross-origin images or frames: arrange same-origin hosting or a compliant proxy; do not expect a library to bypass browser security.

Testing for fidelity and reliability

  1. Capture representative components at the production viewport and pixel ratio.
  2. Load the same web fonts and images used in production, including slow and failed assets.
  3. Compare pseudo-elements, gradients, filters, SVG, fixed positioning, Shadow DOM, and iframe content.
  4. Test Chrome/Chromium, Firefox, and Safari if your users run them.
  5. For automation, wait for network idle plus an application-ready selector; avoid arbitrary sleeps where possible.
  6. Record dimensions, file size, duration, browser version, and failure reason in your own test harness.
  7. Repeat after dependency, browser, or CSS changes. The available documentation does not establish an independent cross-library speed or fidelity winner.

Troubleshooting common failures

Images are missing or tainted

The image is cross-origin without usable CORS headers, or a canvas became tainted. Host the asset on the same origin, configure the remote server for CORS, or use a permitted proxy. useCORS cannot override policy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fonts fall back

Capture occurred before fonts loaded, or the font is unavailable in the runtime. Await document.fonts.ready, verify network responses, and include the font files in the controlled environment.

Output differs from the page

This is expected from DOM reconstruction when a CSS property is unsupported or represented differently. Try a native Playwright/Puppeteer screenshot for page-level fidelity, or simplify the export-specific styles.

Blank or truncated output

Check node dimensions, overflow, lazy content, and capture timing. Scroll or trigger lazy loading, set explicit dimensions, and wait for a readiness selector. For hosted calls, inspect the service’s verdict and billing headers.

Iframe content is absent

Cross-origin iframe content is protected by browser security. Use same-origin content, capture the frame separately with permission, or redesign the export boundary.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Server jobs exhaust memory

Limit concurrent browser pages, reuse contexts carefully, cap image dimensions, close pages in finally blocks, and queue large full-page jobs. Hosted rendering shifts this operations burden to the provider but still depends on network availability.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Bottom line

For a button that exports an on-screen component, test html-to-image, html2canvas, and dom-to-image-more against your real DOM. For a screenshot of a rendered, authenticated page, use Playwright or Puppeteer. For repeatable server captures without running browsers, start with ScreenshotNeo and verify its response verdicts, options, and current terms for your workload.

Frequently Asked Questions

Can I convert HTML to an image without a server?

Yes. html2canvas, html-to-image, and dom-to-image-more run in the user’s browser, subject to CSS support and same-origin/CORS rules.

Is html2canvas a true screenshot?

No. It reconstructs a canvas from DOM and style information rather than asking the browser for a native screenshot.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which option captures a URL I do not already have open?

Use Playwright or Puppeteer to navigate a controlled browser, or use a hosted screenshot API such as ScreenshotNeo.

How should I choose PNG versus JPEG?

Use PNG for transparency, text, and UI sharpness; use JPEG when a smaller photographic image and lossy compression are acceptable. Confirm that your chosen library or service supports the format and quality controls you need.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.