Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use a named PNG file instead of piping image bytes from node-wkhtml’s stdout. Write the HTML to a temporary file, run wkhtmltoimage input.html output.png, check the process exit code, and verify the resulting file. A 2012 Windows report found this avoided corrupt PNG output, but that is historical evidence—not proof that every current Windows or node-wkhtml build has the same defect.
The reliable workaround
node-wkhtml is a Node.js wrapper around the wkhtmltopdf and wkhtmltoimage command-line programs. Its documented stream-oriented pattern can send output to a file stream. The Windows failure described in the original report occurred in that stdout-to-file path: the file was created, but the PNG data was invalid.
The alternative is to let wkhtmltoimage open an input HTML file and write the image itself:
Recommended Free Tools
wkhtmltoimage input.html output.png
The output filename is a real filesystem path, not - (stdout). The command-line utility supports PNG output, and its output setting distinguishes a named path, stdout, and an internal buffer. This direct-file approach was the accepted workaround in the historical report. Validate it with the executable and versions installed on your machine.
#1 Best Overall
- Fast image conversion between PNG, JPG, JPEG, and WEBP.
- High-quality output with no loss in detail.
- Simple and user-friendly interface.
- Completely free and works offline.
- Lightweight app, saves device storage.
Node.js implementation with temporary files
The following is an adaptation of the reported pattern. It creates a unique temporary directory, writes the HTML, starts wkhtmltoimage, checks startup and exit errors, and removes the temporary input in a finally block. It is illustrative code, not a claim that it has been tested against every Windows package.
const fs = require('node:fs/promises');
const path = require('node:path');
const os = require('node:os');
const { spawn } = require('node:child_process');
function runWkhtmltoimage(executable, args) {
return new Promise((resolve, reject) => {
const child = spawn(executable, args, { stdio: 'inherit', windowsHide: true });
child.once('error', reject);
child.once('close', (code, signal) => {
if (code === 0) return resolve();
reject(new Error(`wkhtmltoimage exited with code ${code ?? 'unknown'}${signal ? ` (signal ${signal})` : ''}`));
});
});
}
async function savePng(html, outputFile) {
const executable = process.env.WKHTMLTOIMAGE_PATH || 'wkhtmltoimage';
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'node-wkhtml-'));
const inputFile = path.join(tempDir, 'input.html');
const outputPath = path.resolve(outputFile);
try {
await fs.writeFile(inputFile, html, 'utf8');
await runWkhtmltoimage(executable, [
'--format', 'png',
inputFile,
outputPath
]);
const stat = await fs.stat(outputPath);
if (stat.size < 8) throw new Error('The PNG file is missing or too small to contain a PNG signature');
return outputPath;
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
}
const html = `<!doctype html>
<html><body><h1>Generated image</h1></body></html>`;
savePng(html, './output.png')
.then(file => console.log(`Saved ${file}`))
.catch(error => {
console.error(error);
process.exitCode = 1;
});
Set WKHTMLTOIMAGE_PATH when the executable is not on PATH. For example, in PowerShell:
$env:WKHTMLTOIMAGE_PATH = 'C:Program Fileswkhtmltopdfbinwkhtmltoimage.exe'
node save-png.js
Use a path that exists on the target machine. Do not assume that installing the Node package also installs the native executable.
Minimal child-process pattern
If your application already creates the HTML file, the essential change is to pass both filenames to spawn and avoid a stdout stream:
const { spawn } = require('node:child_process');
const child = spawn('wkhtmltoimage', ['temp.html', 'output.png'], {
stdio: 'inherit'
});
child.on('error', (error) => {
console.error('Could not start wkhtmltoimage:', error);
});
child.on('close', (code) => {
if (code !== 0) {
console.error(`wkhtmltoimage exited with code ${code}`);
}
});
In production, add temporary-file creation, cleanup, an explicit executable path, and a check that the output exists. The close event gives you the process result; the error event catches failures to start the process at all.
Windows command-line procedure
- Save the HTML as a temporary file, such as
C:workcaptureinput.html. Use UTF-8 and make sure relative assets resolve from the location you expect. - Open PowerShell or Command Prompt and check the executable:
wkhtmltoimage --version
wkhtmltoimage --help
- Run the direct-file conversion:
wkhtmltoimage "C:workcaptureinput.html" "C:workcaptureoutput.png"
- Inspect the exit code. In PowerShell, run
$LASTEXITCODE; in Node.js, use theclosehandler shown above. - Confirm that
output.pngexists and opens in an image viewer. Keep the file for diagnosis before deleting temporary data.
If your local help identifies a format switch, you can make the format explicit:
Rank #2
- Download High-Quality Transparent PNG Images
- Explore Animals, Birds, Nature, Fruits and Objects
- Creative Effects and Overlays for Your Projects
- Fast Search and Easy PNG Downloads
- Simple and User-Friendly Interface
wkhtmltoimage --format png "input.html" "output.png"
Use the spelling and options printed by the executable installed on your machine; packaged builds can differ.
Why direct file output can avoid the reported failure
With stdout mode, the Node process receives binary bytes and is responsible for forwarding them unchanged to a file. The historical Windows report says that this workflow produced corrupt PNG data. With a named output path, the native utility performs the file write itself, so the Node stdout pipeline is removed from the path.
The available evidence does not identify the corruption mechanism. It does not establish that Windows universally alters binary stdout, nor that all node-wkhtml releases are affected. Treat direct output as a practical workaround to test, not as a universal diagnosis.
| Workflow | Use it when | Trade-offs |
|---|---|---|
| node-wkhtml stdout stream to a file | Your existing code works and produces a valid PNG in the target environment | Fits stream-oriented code, but the historical Windows report describes corrupt output in this path |
Temporary HTML plus direct wkhtmltoimage input.html output.png |
Stdout output is corrupt or you need a simpler diagnostic path | Requires temporary-file lifecycle management and local validation; the historical accepted answer reported success for its author |
How to tell whether the PNG is valid
A file extension is not enough. A PNG begins with the eight-byte signature 89 50 4E 47 0D 0A 1A 0A. You can inspect the first bytes in PowerShell:
$bytes = [System.IO.File]::ReadAllBytes('output.png')
$bytes[0..7] | ForEach-Object { '{0:X2}' -f $_ }
You should see 89 50 4E 47 0D 0A 1A 0A. Also check that the file has a non-zero, plausible size and opens in more than one viewer if the result matters. A correct signature does not guarantee that every image chunk is complete, so retain the process exit code and test the actual image consumer.
Troubleshooting checklist
“spawn wkhtmltoimage ENOENT” or a similar startup error
Node cannot find the executable. Install the native wkhtmltoimage program, add its directory to PATH, or set WKHTMLTOIMAGE_PATH to the full .exe path. Confirm it with wkhtmltoimage --version in the same environment that runs Node.
Rank #3
- GIMP – The #1 alternative and fully compatible with Adobe Photoshop and Adobe Photoshop Elements files, it is the ultimate fully featured digital image and photo editing software. Restore old photos, change the background, enhance and manipulate images, or simply create your masterpiece from scratch. Multilingual - English, Spanish (Español) and more languages supported.
- Full Tool Suite - Graphic designers, photographers, illustrators, artists and beginners can utilize many tools including channels, layers, filters, effects and more. A plethora of file formats are supported including .psd, .jpg, .gif, .png, .pdf, .hdr, .tif, .bmp and many more.
- Full program that never expires - Free for-life updates and a lifetime license. No yearly subscription or key code is required ever again!
- Multi-Platform Edition DVD-ROM Disc – Compatible with Microsoft Windows PC and Mac.
- PixelClassics Bonus Content – Access to 2.7 MILLION royalty-free stock images photo repository, Installation Menu (PC only), Quick Start Guides and comprehensive User Manual PDF.
The process starts but exits with a non-zero code
Capture stderr by changing stdio from 'inherit' to an arrangement that records the child’s error output, or run the exact command in a terminal. Check the input path, output directory permissions, command-line options, and the executable’s help text. A non-zero status means the conversion did not complete successfully; do not publish the output merely because a file was created.
The PNG is zero bytes, tiny, or unreadable
First retry with the direct-file command and a simple local HTML page. If that works, add the original page’s scripts, styles, images, and fonts one group at a time. Verify that the output directory exists and that another process is not holding the file. Check the PNG signature before investigating application-level image problems.
Images or styles are missing
Use absolute URLs or correct paths relative to the temporary HTML file, and verify that the converter can reach every asset. A temporary file in the system directory changes the base location for relative resources. If the page depends on JavaScript, allow the page to finish according to the options supported by your installed build and test the resulting HTML independently.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →It works interactively but fails as a service
Compare the service account’s permissions, working directory, environment variables, and access to network or local assets. Use absolute paths for both the executable and output. Log the complete argument list (without secrets), exit code, stderr, and the final output path.
Direct file output fails too
The workaround then has not isolated the cause. Check the installed executable, its version, argument syntax, HTML validity, asset access, and compatibility between your Node wrapper and native binary. The historical material does not identify a current Windows-specific cause, so avoid assuming that stdout is the only possible fault.
Operational details for dependable conversions
Temporary-file safety
Create a unique directory with fs.mkdtemp rather than a predictable filename. Remove it in finally, including after a timeout or failed conversion. Keep the final PNG outside that temporary directory until validation is complete.
Rank #4
Concurrency
Each conversion should have its own input and output paths. Unique directories prevent concurrent jobs from overwriting one another. If you queue many conversions, set an application-level limit appropriate for the CPU and memory available; no benchmark establishes a universal worker count.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteTimeouts and cancellation
A child process can remain alive when a page never finishes loading. Add a timer around the spawned process, terminate it on timeout, remove temporary files, and report the URL or job identifier in logs. Choose the timeout from your page behavior rather than copying a value from another environment.
Version and environment checks
Record the operating system, Node.js version, node-wkhtml version, native executable version, exact arguments, and whether the run used stdout or a named output path. Reproduce failures with a minimal local HTML file before changing several variables at once.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. One request returns PNG, JPEG, WebP, or PDF, so you do not need to install a browser wrapper or manage a Windows child process. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled.
Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response identifies the result with X-Page-Verdict and X-Billed headers. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Free tools Windows power users keep installed
One-click scans. No signup required.
See the ScreenshotNeo API documentation for authentication and options. This is the one-call PNG example:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Despite the filename in this example, the API can return PNG, JPEG, or WebP according to the request options. Equivalent Node.js and Python calls are:
Best Value
- [FAQ]
- Q:can not select the image GIF. How do I do?
- A:I am sorry. It does not correspond to the format GIF.
- [Notes]
- There is a thing that some terminals are crashing when saved the image quality to 100%.
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 body = Buffer.from(await res.arrayBuffer());
require('node:fs').writeFileSync('shot.webp', body);
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)
Its capture options include full-page screenshots with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or a custom viewport, retina scale, PDF paper settings and page ranges, HTML/CSS-to-image, custom JavaScript and CSS, clicks, selector or network-idle waits, request and resource blocking, headers, cookies, user agent, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching TTL, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and familiar parameter names for easier migration.
| Plan | Included shots | Price |
|---|---|---|
| Free | 1,000 per month | $0; no card |
| Starter | 3,000 | $5 |
| Growth | 15,000 | $15 |
| Pro | 60,000 | $39 |
| Scale | 250,000 | $99 |
| Business | 1,000,000 | $249 |
Yearly billing gives two months free, and every feature is available on every plan. If cookie banners, popups, chat widgets, failed pages, or AI-agent access are the reason you are maintaining a local browser setup, try ScreenshotNeo’s free account: 1,000 screenshots a month are included with no card, and paid plans start at $5 for 3,000 shots.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Choosing between the two approaches
Keep node-wkhtml when you need a local, offline conversion, already control the native executable, or must integrate with an existing filesystem workflow. Switch the output path from stdout to a named PNG first, then measure reliability in your own Windows environment.
Use ScreenshotNeo when you prefer an HTTP call, need consent and popup cleanup, want failed loads excluded from billing, or want an MCP interface for AI agents. It removes the browser-installation and Windows process-management work, but it is a hosted service and therefore requires an API key and network access.
Frequently Asked Questions
Does a successful exit code guarantee a valid PNG?
No. Check that the output exists, inspect the eight-byte PNG signature, and open or parse the image with the consumer that will use it.
Can I keep using stdout if it works on my machine?
Yes. The stream workflow is documented and may be suitable when it produces valid files in your target environment; use direct named-file output when Windows stdout produces corruption or when you need a simpler diagnostic path.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsWhere should the native executable path be configured?
Put it on PATH or set the application’s WKHTMLTOIMAGE_PATH environment variable to the full wkhtmltoimage.exe path, then verify that exact path with –version.
Quick Recap
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.

