Skip to content

Instantly share code, notes, and snippets.

@LadyNaggaga
Created February 15, 2026 00:14
Show Gist options
  • Select an option

  • Save LadyNaggaga/b7c59c25ef28ced9a759575f7e3e9f9d to your computer and use it in GitHub Desktop.

Select an option

Save LadyNaggaga/b7c59c25ef28ced9a759575f7e3e9f9d to your computer and use it in GitHub Desktop.
name description
html-to-png
Use this skill whenever you want to convert an HTML, JavaScript, or CSS diagram, visualization, or UI component into a transparent PNG image. Triggers include any mention of 'export to PNG', 'transparent PNG', 'save as image', 'screenshot of HTML', 'render to PNG', or requests to turn web-based visuals (diagrams, charts, infographics, architecture drawings, flowcharts, etc.) into downloadable image files. Also use when you have an existing HTML file and want a static image version. Do NOT use for PDF generation, video/GIF recording, or non-image export formats.

HTML to Transparent PNG

Overview

This skill converts HTML/CSS/JS content into high-resolution transparent PNG images using Puppeteer and headless Chrome. It handles font loading, CSS animations (waiting for them to settle), retina-quality rendering, and transparent backgrounds.

When to Use

  • You have an HTML file or inline HTML/CSS/JS and want a PNG
  • You need a "transparent PNG", "export to image", or "render as PNG"
  • You created a diagram, chart, infographic, or visualization in HTML and want an image file
  • You want a high-resolution image suitable for slides, documents, or print

Prerequisites

  • Node.js (v16 or later)
  • Chrome/Chromium installed on your system

Quick Start

Step 1: Prepare the HTML

Before rendering, ensure the HTML has a transparent background. If the HTML has a solid background on body or the root container, change it:

/* BEFORE — opaque */
body { background: #0a0c10; }

/* AFTER — transparent */
body { background: transparent; }

Important: Only make body (or html) transparent. Inner elements should keep their backgrounds so card/panel styling is preserved. The goal is that the overall canvas is transparent while the content floats on top.

If the HTML was originally designed with a dark background, the text and element colors are probably light. These will still look correct on any dark surface the PNG is placed on. If you need it to work on light backgrounds too, adjust text colors accordingly.

Step 2: Install Dependencies

Option A: Full Puppeteer (downloads Chromium automatically)

npm install puppeteer

Option B: Puppeteer-core (use existing Chrome installation)

npm install puppeteer-core

If using Option B, you must specify the Chrome executable path in the script (see Step 3).

Step 3: Create the Render Script

Create a file named render_png.js with the following content:

const puppeteer = require('puppeteer'); // or 'puppeteer-core'
const path = require('path');

const [,, inputHtml, outputPng, width = 900, height = 900, scale = 2, waitMs = 2500] = process.argv;

if (!inputHtml || !outputPng) {
  console.error('Usage: node render_png.js <input.html> <output.png> [width] [height] [scale] [wait_ms]');
  process.exit(1);
}

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
    // Uncomment and set path if using puppeteer-core:
    // executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', // Windows
    // executablePath: '/usr/bin/google-chrome', // Linux
    // executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', // macOS
  });

  const page = await browser.newPage();
  await page.setViewport({
    width: parseInt(width),
    height: parseInt(height),
    deviceScaleFactor: parseInt(scale),
  });

  const filePath = path.resolve(inputHtml);
  await page.goto(`file://${filePath}`, { waitUntil: 'networkidle0' });
  await new Promise(r => setTimeout(r, parseInt(waitMs)));

  await page.screenshot({
    path: outputPng,
    omitBackground: true, // Enables transparency
    fullPage: false,
  });

  await browser.close();
  console.log(`PNG saved to: ${outputPng}`);
})();

Step 4: Run the Script

node render_png.js <input.html> <output.png> [width] [height] [scale] [wait_ms]

Parameters:

Param Default Description
input.html (required) Path to the HTML file
output.png (required) Path for the output PNG
width 900 Viewport width in pixels
height 900 Viewport height in pixels
scale 2 Device scale factor (2 = retina/2x resolution)
wait_ms 2500 Milliseconds to wait after page load for animations to settle

Examples:

# Default: 900×900 at 2x (outputs 1800×1800 PNG)
node render_png.js diagram.html diagram.png

# Wide format for presentations (1920×1080 at 2x → 3840×2160)
node render_png.js slide.html slide.png 1920 1080 2 1000

# Square social media image at 3x
node render_png.js card.html card.png 1080 1080 3 2000

# Fast render, no animations to wait for
node render_png.js simple.html simple.png 800 600 2 100

The output PNG will be saved to the specified output path.


Complete Workflow Example

Here's the full sequence for converting an existing HTML diagram:

# 1. Install puppeteer
npm install puppeteer

# 2. Create render_png.js (see Step 3 above)

# 3. If the HTML needs background made transparent, edit the body background in the HTML file

# 4. Render
node render_png.js my-diagram.html my-diagram.png 900 900 2 2500

# 5. Verify (Linux/macOS)
file my-diagram.png  # Should show: PNG image data, RGBA

# 5. Verify (Windows PowerShell)
# Check file exists and open to verify
Get-Item my-diagram.png

Handling Common Scenarios

HTML with animations

Set wait_ms high enough for all CSS animations and transitions to complete. Inspect the CSS — find the longest animation-duration + animation-delay and add 500ms buffer. Default 2500ms handles most cases.

Google Fonts or external fonts

The script uses waitUntil: 'networkidle0' which waits for all network requests (including font loads) to finish. If fonts still don't render, increase wait_ms.

Content overflows the viewport

The script clips to the viewport dimensions. Either:

  • Increase width/height to fit all content, or
  • Redesign the HTML to fit the target dimensions

User wants a non-transparent PNG

If you explicitly want a solid background, keep the body background color in the HTML. Then set omitBackground: false in the script, or simply leave the background — Puppeteer's omitBackground: true only removes the default white background; if the HTML sets its own background color, that color renders into the PNG.

Converting an existing HTML file

To export an existing HTML file:

  1. Copy the HTML content into a file (e.g., artifact.html)
  2. Modify the body background to transparent if needed
  3. Run the render script
  4. Use the output PNG as needed

Sizing for common use cases

Use Case Width Height Scale Result
Slide (16:9) 1920 1080 2 3840×2160
Slide (4:3) 1440 1080 2 2880×2160
Square diagram 900 900 2 1800×1800
Social media 1080 1080 2 2160×2160
Banner 1200 630 2 2400×1260
Icon/Badge 256 256 3 768×768

Troubleshooting

Problem Solution
Chrome not found Set executablePath in the script to your Chrome installation path
Chrome crashes / Target closed Add --single-process --no-zygote to the args array
Blank/white PNG HTML body background is white; make it transparent
Fonts not loading Increase wait_ms or check network access to font CDN
Content cut off Increase width and/or height
Blurry output Increase scale (2 is standard retina, 3 for extra crisp)
Script hangs Reduce wait_ms; check for infinite JS animations blocking idle
puppeteer not found Run npm install puppeteer in your project directory

Platform-Specific Chrome Paths

Platform Typical Chrome Path
Windows C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe
macOS /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
Linux /usr/bin/google-chrome or /usr/bin/chromium-browser
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment