Use the Sharp package: install it with npm install sharp, read the PNG, call .webp(), and write the result with .toFile(). The shortest asynchronous conversion is:
import sharp from 'sharp';
await sharp('input.png')
.webp()
.toFile('output.webp');
This guide covers ESM and CommonJS projects, quality and lossless settings, buffers, metadata, runtime requirements, production checks, and common failures.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
How to Use Photopea: A Beginner User Guide 2026: Step-by-Step Lessons for Background Removal, Layer... | $12.99 | Buy on Amazon |
Install Sharp and check your Node.js runtime
From your project directory, run:
npm install sharp
The current Sharp project overview lists support for Node.js 20.9.0 or newer and says most modern macOS, Windows and Linux systems need no extra runtime dependency. Verify the requirements for the exact Sharp release and deployment platform you install, because supported versions can change. See the Sharp project overview for the current baseline.
Choose the module syntax your project already uses
Use the ESM import shown below when your package uses "type": "module" or an equivalent ESM configuration:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
import sharp from 'sharp';
In a CommonJS project, use the form supported by your installed Sharp release and Node configuration, commonly:
const sharp = require('sharp');
Do not mix module systems accidentally. A module-format error is a project configuration problem, not a PNG conversion problem.
Convert one PNG to WebP
Minimal ESM script
Create convert.mjs (or use an ESM-enabled .js file):
import sharp from 'sharp';
await sharp('input.png')
.webp()
.toFile('output.webp');
console.log('Wrote output.webp');
sharp('input.png') opens the source, .webp() selects the WebP encoder, and .toFile('output.webp') writes the encoded file. When no callback is supplied, toFile returns a Promise, so await lets Node report completion or throw an error.
Free tools Windows power users keep installed
One-click scans. No signup required.
A reusable function with output details
The output object includes information such as format, byte size, dimensions and channel count. That is useful for logging or for rejecting an unexpected result:
import sharp from 'sharp';
async function pngToWebp(inputPath, outputPath) {
const result = await sharp(inputPath)
.webp()
.toFile(outputPath);
console.log({
file: outputPath,
format: result.format,
size: result.size,
width: result.width,
height: result.height,
channels: result.channels
});
}
try {
await pngToWebp('input.png', 'output.webp');
} catch (error) {
console.error('Conversion failed:', error.message);
process.exitCode = 1;
}
The destination directory must already exist and be writable by the Node process. Sharp does not create missing parent directories for this call.
Control WebP quality, size and fidelity
Sharp documents a default WebP quality of 80 and effort of 4. Those are starting points, not guarantees of a particular visual result or file-size reduction. Compare representative images from your own workload and choose the setting that meets your appearance, byte-size and processing-time requirements.
Lossy WebP with explicit quality
import sharp from 'sharp';
await sharp('input.png')
.webp({ quality: 82, effort: 4 })
.toFile('output.webp');
The documented quality range is 1–100. Higher quality generally asks the encoder to preserve more visual detail, while the resulting size and processing behavior depend on the image and the other options.
Lossless and near-lossless modes
If exact pixel preservation is required, use the documented lossless mode and verify the result for your assets:
import sharp from 'sharp';
await sharp('input.png')
.webp({ lossless: true, effort: 4 })
.toFile('output-lossless.webp');
Sharp also exposes near-lossless mode. It can be useful when you want behavior between ordinary lossy compression and strict losslessness, but the acceptable trade-off is image-specific.
Encoder options worth evaluating
| Option | What it controls | How to decide |
|---|---|---|
quality |
Lossy WebP quality, documented from 1 to 100 | Compare visual artifacts and bytes on representative PNGs. |
lossless |
Requests lossless WebP encoding | Use when pixel fidelity is more important than minimum size. |
nearLossless |
Near-lossless encoding mode | Evaluate when ordinary lossy output is too visibly different. |
alphaQuality |
Quality setting for the alpha channel | Test on transparent graphics, logos and soft edges. |
smartSubsample |
Smart chroma-subsampling behavior | Check colored text, fine edges and brand graphics. |
preset |
Encoder preset | Measure its effect on your content instead of assuming a universal best preset. |
effort |
Encoding effort, documented from 0 to 6 | Higher effort can trade processing time for encoding behavior; benchmark your queue if it matters. |
These controls are documented in Sharp’s output API. There is no reliable single quality value that is optimal for every PNG.
Return a WebP buffer instead of creating a file
Use toBuffer() when you need to upload the result, send it in an HTTP response, or pass it to another API without an intermediate destination file:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteimport sharp from 'sharp';
const webpBuffer = await sharp('input.png')
.webp({ quality: 82 })
.toBuffer();
console.log(`Encoded ${webpBuffer.length} bytes`);
// Upload webpBuffer or return it from your request handler.
The call still needs .webp(); toBuffer() alone does not select an output format. Buffer conversion keeps the encoded bytes in memory, so account for the size and concurrency of images your process handles.
Metadata and orientation behavior
Sharp removes metadata by default, including EXIF-based orientation. This is often desirable for smaller, privacy-conscious web assets, but it can surprise workflows that depend on camera metadata or embedded profiles.
Preserve metadata deliberately
import sharp from 'sharp';
await sharp('input.png')
.withMetadata()
.webp()
.toFile('output-with-metadata.webp');
Use withMetadata() only when retention is part of your requirement. Confirm the output in the application that will consume it; preserving metadata can affect bytes and downstream behavior.
Paths, directories and batch conversion
Use explicit paths
Relative paths are resolved from the process’s current working directory, not necessarily from the script file. For predictable jobs, pass absolute paths or build them with Node’s path utilities, and create the destination directory before calling toFile.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →import { mkdir } from 'node:fs/promises';
import path from 'node:path';
import sharp from 'sharp';
const outputDir = path.resolve('converted');
await mkdir(outputDir, { recursive: true });
await sharp(path.resolve('input.png'))
.webp()
.toFile(path.join(outputDir, 'input.webp'));
Convert several known files
For a small, controlled list, await each conversion so failures identify the file that caused them:
import sharp from 'sharp';
const files = ['one.png', 'two.png', 'three.png'];
for (const input of files) {
const output = input.replace(/.png$/i, '.webp');
await sharp(input).webp().toFile(output);
console.log(`${input} -> ${output}`);
}
For large batches, choose concurrency appropriate to your CPU and memory. The supplied Sharp documentation does not establish a universal throughput figure, so measure your own images and deployment rather than relying on a benchmark from another workload.
Validate the result and compare settings
A conversion succeeded when Sharp resolves and reports an output, but production pipelines should still check:
- The output file exists and is readable by the next process.
- The reported format is WebP and dimensions match the intended image.
- Transparent edges, text and gradients look acceptable.
- Byte size meets your delivery or storage budget.
- Metadata behavior matches your privacy and application requirements.
Keep a small representative fixture set: photographic PNGs, screenshots, flat-color illustrations, text-heavy graphics and transparent assets. Run the same files through candidate quality, alpha and effort settings, then inspect both appearance and bytes. Do not claim that WebP always produces a smaller file; source content and encoder options determine the result.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Troubleshoot common conversion errors
“Cannot find module ‘sharp’”
Install the dependency in the project whose script is running: npm install sharp. Check that you are in the correct directory and that the package appears in dependencies, not only in a different workspace.
ESM/CommonJS import errors
Match the import form to your package configuration and installed Sharp release. Use ESM syntax in an ESM project and the supported CommonJS form in a CommonJS project; do not paste both into one file.
Input file does not exist or is not a PNG
Print the resolved input path and verify its permissions and extension. An extension alone does not prove the file is valid PNG data; pass a readable image file to Sharp and inspect the thrown error.
“ENOENT” or “EACCES” on output
ENOENT commonly means the parent directory is missing; create it before toFile. EACCES means the process cannot write there; choose a writable directory or fix the deployment permissions.
Recommended Free Tools
The image looks rotated or metadata is missing
Sharp strips metadata, including EXIF orientation, by default. If the consuming workflow requires metadata, add withMetadata() and verify the resulting file.
The output is too large or visibly degraded
Run a controlled comparison with quality, alpha quality, lossless or near-lossless and effort settings. Inspect the exact images that matter; changing one setting can help one asset and hurt another.
Or skip the browser setup
If your separate task is taking clean screenshots of webpages rather than converting a local PNG, ScreenshotNeo provides a one-request screenshot API. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status.
For example, capture a webpage as WebP with cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for options such as full-page capture, CSS-selector element shots, device and retina settings, dark mode, custom CSS or JavaScript, waits, request blocking, cookies, headers, geolocation, caching, signed links, asynchronous jobs and bulk capture. Its MCP server supplies take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.
The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan. Create a free ScreenshotNeo account.
Use the conversion in an HTTP response
When an endpoint should return WebP directly, convert to a buffer and set the response type. This example uses the standard Fetch-style Response object:
import sharp from 'sharp';
export async function pngAsWebp() {
const data = await sharp('input.png')
.webp({ quality: 82 })
.toBuffer();
return new Response(data, {
headers: { 'content-type': 'image/webp' }
});
}
Adapt the response wrapper to your Node framework. Keep the conversion errors visible in logs and return an appropriate HTTP error when the input cannot be read or encoded.
Reference links and version hygiene
Sharp’s project overview documents supported input and output formats, installation and runtime notes. Its output API documents toFile, toBuffer, WebP encoder controls and metadata behavior. Recheck both pages when upgrading Node or Sharp, especially for serverless, container and operating-system builds.
Frequently Asked Questions
Can I overwrite the original PNG?
You can choose the same path only after deciding how your pipeline handles replacement, but writing a separate .webp file first is safer because a failed conversion leaves the source intact.
Does the WebP file keep the PNG filename?
The encoded format is determined by .webp(); use a filename ending in .webp and send or store it with the image/webp content type.
What should I do when a project must support an older Node release?
Check the Sharp release documentation and its supported runtime matrix before installing. The current project overview lists Node.js 20.9.0 or newer, but that requirement can change with future releases.
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.

