← Back to Blog

HTML to Image API: Convert HTML/CSS to PNG or JPEG

February 19, 2026 · 10 min read

Need to turn HTML and CSS into an image? Whether you're generating social media cards, invoices, certificates, email headers, or dynamic OG images, an HTML to image API handles the rendering so you don't have to run your own headless browser.

This guide covers every approach: self-hosted libraries, hosted APIs, and when to use each. With working code examples in Node.js, Python, and cURL.

Why convert HTML to images?

HTML and CSS give you pixel-perfect control over layout, typography, and colors. But many platforms only accept images:

Approach 1: Self-hosted with Puppeteer

Run headless Chrome on your own server. Full control, but you manage the infrastructure.

const puppeteer = require('puppeteer');

async function htmlToImage(html) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Set the HTML content directly
  await page.setContent(html, { waitUntil: 'networkidle0' });

  // Capture the rendered output
  const screenshot = await page.screenshot({
    type: 'png',
    fullPage: true
  });

  await browser.close();
  return screenshot;
}

// Usage
const html = `
<div style="width:1200px;height:630px;background:linear-gradient(135deg,#667eea,#764ba2);
  display:flex;align-items:center;justify-content:center;font-family:Inter,sans-serif">
  <h1 style="color:white;font-size:48px">Hello World</h1>
</div>`;

const image = await htmlToImage(html);
fs.writeFileSync('output.png', image);

Downsides of self-hosting

Approach 2: Screenshot API (recommended for production)

A hosted API handles the browser infrastructure. You send a URL or HTML, get an image back. No servers to manage.

GrabShot handles this for you

25 free screenshots per month. Full browser rendering with custom viewports, wait conditions, and format options. Get your free API key →

Node.js

const axios = require('axios');

const response = await axios.get('https://grabshot.dev/v1/screenshot', {
  params: {
    url: 'https://your-html-template.com/card?name=John',
    width: 1200,
    height: 630,
    format: 'png'
  },
  headers: { 'X-API-Key': 'your-api-key' },
  responseType: 'arraybuffer'
});

fs.writeFileSync('card.png', response.data);

Python

import requests

response = requests.get('https://grabshot.dev/v1/screenshot', params={
    'url': 'https://your-html-template.com/card?name=John',
    'width': 1200,
    'height': 630,
    'format': 'png'
}, headers={'X-API-Key': 'your-api-key'})

with open('card.png', 'wb') as f:
    f.write(response.content)

cURL

curl "https://grabshot.dev/v1/screenshot?url=https://example.com&width=1200&height=630&format=png" \
  -H "X-API-Key: your-api-key" \
  --output card.png

Approach 3: Client-side libraries

Libraries like html2canvas and dom-to-image run in the browser. They're useful for "save as image" features but have significant limitations:

For production use cases where consistency matters, a real browser engine (Puppeteer or a screenshot API) gives you pixel-perfect results every time.

Common use case: Dynamic OG images

One of the most popular HTML to image use cases is generating Open Graph images for social media. Here's a pattern that works:

  1. Create an HTML template with CSS for your card design
  2. Host it as a route (e.g., /og?title=My+Post&author=Jane)
  3. Use a screenshot API to render it at 1200x630
  4. Cache the result and serve it as your og:image
// Express route that generates OG images on the fly
app.get('/og-image/:slug', async (req, res) => {
  const post = await getPost(req.params.slug);
  const imageUrl = `https://grabshot.dev/v1/screenshot?` +
    `url=${encodeURIComponent(`https://mysite.com/og-template?title=${post.title}`)}&` +
    `width=1200&height=630&format=png`;

  const img = await fetch(imageUrl, {
    headers: { 'X-API-Key': process.env.GRABSHOT_KEY }
  });

  res.set('Content-Type', 'image/png');
  res.set('Cache-Control', 'public, max-age=86400');
  res.send(Buffer.from(await img.arrayBuffer()));
});

Read our full guide on automating OG image generation for more details.

API comparison: HTML to image services

Service Free tier Paid from HTML input
GrabShot 25/mo $9/mo URL + raw HTML
ScreenshotOne 100/mo $29/mo URL + raw HTML
Urlbox 7-day trial $39/mo URL + raw HTML
APIFlash 100/mo $7/mo URL only

See it in action

Try GrabShot right now — paste any URL and get a screenshot instantly. No signup needed.

Try Free Screenshot Tool →