PicoWebP: Building a WebP Encoder in PHP by Niko MinadzePicoWebP: Building a WebP Encoder in PHP by Niko Minadze

PicoWebP: Building a WebP Encoder in PHP

Niko Minadze

Niko Minadze

PicoWebP: Building a WebP Encoder in PHP

PicoWebP started with a small hosting problem that interested me: a website can run PHP, but the tools it needs to produce WebP images aren't available.
This can happen on shared hosting. GD might be installed without WebP support, and adding another extension or a command-line converter may be outside the developer's control. Moving the site or introducing an external image service is a lot of work for what looks like a simple conversion task.
I wanted to see how much of that problem I could solve inside a Composer package. Part practical fallback, part excuse to work on something technically interesting.
The result is PicoWebP: an open-source library that converts PNGs, baseline JPEGs and raw RGB pixels into WebP using PHP. For those inputs, it works without GD, Imagick, cwebp or libwebp. The requirements are PHP 8.1 or newer and the zlib extension.
The interesting part is what happens underneath. PicoWebP writes the VP8 bitstream itself. It takes pixel data through prediction, transforms, quantisation and compression, then packages the result as a WebP file that other decoders can read. The encoding work happens inside PHP.
Reading the source image needed the same attention. Depending on an unavailable extension to open a PNG would leave the original problem unresolved, so the package includes its own PNG and baseline JPEG readers. GD remains optional and can speed up decoding when it is available. Progressive JPEG input still requires it.
Getting a recognisable picture out was only part of the work. A transparent logo needs to remain transparent. An embedded colour profile needs to survive the conversion. A file that is already WebP should be recognised even if someone has named it photo.jpg.
PicoWebP preserves the PNG reader's full eight-bit alpha as lossless transparency alongside the lossy colour data, and carries ICC profiles into the output. It also checks file contents instead of trusting extensions, skipping existing WebP files by default. These details make it easier to integrate into an application handling mixed uploads.
I packaged it with both a PHP API and a CLI, so it can fit into an existing application or be tried from the terminal. Installation uses Composer:
composer require nikocodes/picowebp
With a baseline JPEG in the current directory, this converts it using the bundled reader:
vendor/bin/picowebp photo.jpg photo.webp --quality=80 --no-gd
The same command accepts a PNG. The --no-gd flag makes it explicit that GD will not be used. Developers can also request JSON output and use the CLI's exit codes to distinguish a completed conversion, a skipped file and an error.
PNG + baseline JPEG work with the bundled readers.
PNG + baseline JPEG work with the bundled readers.
Long-running conversions are another consideration on restricted hosting. I added a resumable encoding path that stages intermediate data on disk and processes the image in bands. An application can save the state and continue in another invocation. The application still supplies the scheduling and persistence; the library provides the encoding mechanism.
The tests cover more than whether a file gets written. They exercise the bitstream, image readers, transparency, colour profiles, malformed input, CLI behaviour and resumed encoding. When dwebp is available, additional checks decode the output using libwebp. Checking the result with a separate decoder is useful when implementing a file format.
The main trade-off is CPU time. Native libwebp is substantially faster and is the better choice when it is available. With default settings on my PHP 8.4 macOS benchmark, encoding roughly one megapixel took about 25 seconds. PicoWebP belongs in background processing with sensible input limits, rather than in a visitor's page request. Resumability helps divide the work; it does not make that work faster. EXIF metadata and automatic orientation are also outside its current scope.
I don't expect most PHP projects to need their own WebP encoder. I like that this one answers a specific constraint and is available when that constraint matters. It was also an enjoyable way to work below the usual application layer and turn the result into something another developer can install, inspect and use.
PicoWebP is published under the MIT license. The project page on NikoCodes covers the current release, Packagist provides the Composer package, and GitHub contains the source, examples and tests. More of my projects are at nikocodes.com.
Like this project

Posted Sep 20, 2026

I built PicoWebP, a pure-PHP WebP encoder for restricted hosting, preserving transparency and colour profiles without GD, Imagick or libwebp.