You have an HTML template — a social card, a report, an invoice, a dashboard widget — and you need it as a PNG image. There are five main approaches, each with different trade-offs in automation, quality, and operational complexity.
This guide compares all five with working code examples so you can pick the right one for your use case.
1. Browser DevTools (Manual Screenshot)
The simplest approach: open your HTML in a browser, right-click, and screenshot.
How it works:
- Open Chrome DevTools (F12)
- Select the element you want to capture
- Right-click the node in the Elements panel → "Capture node screenshot"
- Or use
Cmd+Shift+P→ "Capture full size screenshot"
Best for: One-off screenshots for design review or bug reports.
Limitations: Not automatable. Viewport size, DPI, and rendering vary between machines. Useless for any programmatic workflow.
2. Puppeteer (Headless Chrome)
Puppeteer gives you full control over a headless Chromium instance. You can render any HTML and call page.screenshot().
const puppeteer = require('puppeteer')
async function htmlToPng(html) {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.setViewport({ width: 1200, height: 630, deviceScaleFactor: 2 })
await page.setContent(html, { waitUntil: 'networkidle0' })
const png = await page.screenshot({ type: 'png', omitBackground: true })
await browser.close()
return png
}Best for: When you need JavaScript execution (dynamic charts, Canvas elements) or complex browser interactions before the screenshot.
Limitations:
- Chromium is ~400MB — Docker images are large
- Memory leaks from zombie browser processes in long-running services
- Cold start 2-5 seconds per browser launch
- Concurrency is hard — each page needs ~100-200MB RAM
In production, Puppeteer processes can accumulate and eat all available memory. You need process management, health checks, and container resource limits. Most teams underestimate this until they get paged at 3am.
3. wkhtmltoimage (Qt WebKit CLI)
A command-line tool that converts HTML to images using an embedded WebKit engine.
wkhtmltoimage --width 1200 --quality 100 input.html output.pngBest for: Legacy systems with simple HTML that don't use modern CSS.
Limitations: Uses an outdated WebKit engine. No CSS Grid, no Flexbox, no Tailwind CSS, no custom web fonts. Essentially frozen in 2016-era rendering. Most modern HTML will look broken.
4. Online Converters
Web tools where you paste HTML and download a PNG. Examples include html2png.com, hcti.io, and similar services.
Best for: Quick one-off conversions when you don't have developer tools set up.
Limitations: Not programmable. No batch processing. Your HTML is uploaded to a third-party server, which is a privacy concern for sensitive content. Most have aggressive watermarking on free tiers.
5. RendShot API
Full disclosure: this is our product.
A dedicated API that renders HTML to PNG (and JPEG, WebP) in one HTTP call. No browser to manage, no infrastructure to maintain.
const response = await fetch('https://api.rendshot.ai/v1/image', {
method: 'POST',
headers: {
'Authorization': 'Bearer rs_live_your_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: '<div style="font-family: Inter; padding: 40px;">Hello World</div>',
width: 1200,
height: 630,
format: 'png',
transparent: true,
deviceScaleFactor: 2,
}),
})
const { url } = await response.json()
// url → https://assets.rendshot.ai/abc123.png (CDN-hosted)import rendshot
client = rendshot.Client("rs_live_your_key")
result = client.generate(
html='<div style="padding: 40px;">Hello World</div>',
width=1200,
height=630,
format="png",
transparent=True,
)
print(result.url)Best for: Automated, high-volume HTML-to-PNG at scale. OG images, social cards, reports, email images, e-commerce product cards.
Limitations: Requires an API key (free tier: 100 renders/month). No JavaScript execution — your HTML must be self-contained. External images in HTML are subject to SSRF validation.
Comparison Table
| DevTools | Puppeteer | wkhtmltoimage | Online tools | RendShot API | |
|---|---|---|---|---|---|
| Automatable | No | Yes | Yes | No | Yes |
| Modern CSS | Yes | Yes | No | Varies | Yes |
| Tailwind CSS | Yes | Yes | No | No | Yes |
| Transparent BG | No | Yes | No | Varies | Yes |
| Concurrency | N/A | 1-2 per instance | ~10 per instance | N/A | Unlimited |
| Infra required | None | Docker + Chromium | Binary install | None | None |
| Cold start | N/A | 2-5s | <1s | N/A | <1.2s avg |
| Cost | Free | Server costs | Free | Free (limited) | Free tier, then $19/mo |
Latency and cold-start figures are estimates based on typical usage in US-East (early 2026). Your results will vary by hardware, page complexity, and region.
Pricing as of early 2026 — check each provider's site for current rates.
When to Use Which
- Just need a quick screenshot? → Browser DevTools
- Need JS execution or browser interaction? → Puppeteer or Playwright
- Simple HTML on a legacy system? → wkhtmltoimage (if it renders correctly)
- Automated rendering at scale, no infra? → RendShot API
- Evaluating options? → Start with RendShot's free tier (100/mo) and compare
PNG Format Considerations
PNG uses lossless compression — every pixel is preserved exactly. This makes it ideal for:
- UI screenshots — crisp text, sharp edges
- Images with transparency — logos, overlays, composites
- Diagrams and charts — flat colors compress well in PNG
For photos or gradients, JPEG or WebP typically produce 3-5x smaller files for photo-heavy content (based on 1200×630 test renders, early 2026). See our format comparison guide for when to use lossy compression instead.