Client-side, server-side, API, and screenshot — when to use each.
Converting HTML to an image is a deceptively common need. Social cards, email signatures, PDF alternatives, chart exports, receipt generation — any time you need pixel-perfect rendering of styled content as an image file. Here are four approaches, each with different trade-offs.
html2canvas is a JavaScript library that renders HTML elements to a canvas by re-implementing CSS layout in JavaScript. It runs in the browser — no server needed.
import html2canvas from 'html2canvas';
const element = document.getElementById('receipt');
const canvas = await html2canvas(element);
const dataUrl = canvas.toDataURL('image/png');
// Download it
const link = document.createElement('a');
link.download = 'receipt.png';
link.href = dataUrl;
link.click();
Pros: No server, runs in the browser, captures the page as the user sees it, handles dynamic content and user-specific state.
Cons: Doesn't fully implement CSS (flexbox gaps, grid, some transforms fail). No web font support in some cases. Canvas tainted by CORS images. Slow for large elements. Output quality is limited by the screen resolution.
Best for: User-facing "export to image" buttons, capturing user-specific views that only exist in the browser.
Launch a headless browser, load the HTML, take a screenshot. Full CSS support because it's a real browser engine.
import { chromium } from 'playwright';
async function htmlToImage(html) {
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 800, height: 600 } });
await page.setContent(html, { waitUntil: 'networkidle' });
const buffer = await page.screenshot({ type: 'png' });
await browser.close();
return buffer;
}
Pros: Perfect CSS rendering (it's a real browser). Supports web fonts, SVG, canvas, everything. Full control over viewport and DPR.
Cons: Requires headless browser infrastructure. Each conversion costs ~200–500MB of RAM. Slow cold start if you're not keeping the browser warm. Doesn't work in serverless environments without significant workarounds.
Best for: Server-side batch processing where you control the infrastructure and need perfect rendering.
Services like htmlcsstoimage.com accept HTML+CSS input and return an image. They run browsers on their infrastructure so you don't have to.
const response = await fetch('https://hcti.io/v1/image', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('user:key'),
},
body: JSON.stringify({
html: '<div style="padding:40px;background:purple;color:white">Hello</div>',
css: '',
}),
});
const { url } = await response.json();
Pros: No browser to manage. Works from any environment. HTML+CSS input means you can template everything server-side.
Cons: Limited to HTML string input (can't capture live pages). Another API dependency. Pricing varies.
Best for: Generating images from HTML templates — invoices, social cards, certificates, email headers.
Host your HTML as a page (even locally accessible or with data URIs), then screenshot it:
// Host the HTML at a URL, then capture it
const response = await fetch(
'https://api.nightglass.xyz/api/v1/screenshot',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY',
},
body: JSON.stringify({
url: 'https://yoursite.com/templates/invoice?id=12345',
width: 800,
height: 600,
}),
}
);
Pros: Full browser rendering. Can capture any URL (not just HTML strings). Same API you'd use for website screenshots. Supports mockup mode, dark mode, device emulation.
Cons: Requires the HTML to be hosted at a URL. Slightly higher latency than HTML-string APIs (page has to load).
Best for: When you already have the content as a web page and want to capture it as an image. OG image generation, page-to-PDF alternatives, visual snapshots.
| Scenario | Best approach |
|---|---|
| User clicks "Export" in browser | html2canvas |
| Batch processing on your server | Playwright/Puppeteer |
| Generate images from HTML templates | HTML-to-image API |
| Capture live web pages as images | Screenshot API |
| Serverless environment (Lambda, Vercel) | Screenshot API (only option) |
For dynamic social media cards from templates, the OG image guide covers the HTML template + screenshot pattern. For full-page captures, the full-page guide. Comparing API options? 2026 screenshot API comparison.