@wasmedia/wvips
v0.2.0
Published
libvips compiled to WebAssembly for browsers
Maintainers
Readme
wvips
A from-scratch, sustainable libvips build for the browser, compiled to WebAssembly with all modern image-format dependencies. Single-threaded + SIMD — works on any site without special headers (COOP/COEP).
Format & Feature Scope
- Excluded: SVG (rsvg), PDF (poppler/pdfium), JPEG 2000 (OpenJPEG), OpenSlide, NIfTI, FITS, MATLAB, OpenEXR, raw archive support — these are heavy, optional libvips loaders that don't fit a browser bundle.
- HEIC is not supported, neither decode nor encode. libheif is built without an HEVC codec (libde265 to decode, x265 to encode), so loading an iPhone
.heicfails. HEVC carries patent-licensing questions; whether to add libde265 is tracked in #4. - Included: Modern raster formats with encode + decode where the library supports it:
- Common: JPEG (mozjpeg), PNG, WebP, TIFF, GIF (read built-in / write via cgif)
- Modern: AVIF (libheif + libaom), JPEG XL (libjxl)
- Metadata: EXIF (libexif), ICC profiles (lcms2)
- Quantisation: imagequant (palette PNG/GIF)
Technical Requirements
- libvips version: Track current stable (8.18 line at time of writing).
- API surface: Both CLI-style (
vips operation arg1 arg2 ...) and the C API (vips_image_new_from_buffer,vips_thumbnail_buffer,vips_image_write_to_buffer, etc.). - JS wrapper: High-level chainable
WVipsImageclass on top of the C bindings, plus CLI-style command execution. - Toolchain: Emscripten (
emsdk5.0.6) inside Docker; libvips built via meson. - Output: Single
.wasm+ JS glue bundle, distributable as an npm package. - File I/O:
ArrayBuffer/Blobpassing, MEMFS, and file-backed I/O:Image.open()/writeTo()read and write OPFS files (in a worker) or host files (Node) in place, so a large image never has to fit in the heap. - Web Workers: Off-main-thread support via
worker.ts. - Browser support: Chrome and Safari at minimum.
- Build: Single-threaded + SIMD — no special HTTP headers required.
Prior Art
| Project | Status | libvips Version | Build approach | API style | |---------|--------|-----------------|----------------|-----------| | kleisauke/wasm-vips | Active | Tracks stable | Emscripten + Embind, single tarball script | C++/Embind | | lovell/sharp | Active | Tracks stable | Native node addon — not WASM | Node.js only |
What wvips offers in addition:
- A clean separation between the native build (
native/, owned source-by-source from upstream releases) and a TypeScript wrapper (src/) that mirrors the wimagemagick shape:loader,image,cli,api,filesystem,worker. - CLI-style command execution (
wim.execute('input.png -resize 50% output.jpg', files)), not just programmatic API. - No reliance on a third-party prebuilt blob — every dependency is fetched from upstream and built inside our Docker image so we own the bill of materials and the upgrade story.
Try it
The browser playground is live at https://vips.wasmedia.org — drop an image, resize and convert it entirely client-side. It is rebuilt from main on every merge.
Install
npm install @wasmedia/wvipsPublished to npmjs.org with provenance, like the rest of the wasmedia family. No .npmrc is needed. 0.1.0 was published only to GitLab's npm registry.
Quick start
npm run build # native WASM (Docker) + TypeScript
npm run playground # serve examples/browser/index.html on :8000See docs/building.md for the long form and docs/api.md for the JS/TS API.
For large images and memory behaviour, see docs/file-io.md.
License
- wvips's own code (the TypeScript wrapper, the C bindings, the build tooling) is Apache-2.0.
dist/wvips.wasmstatically links libvips, glib and libexif (LGPL-2.1-or-later), libheif (LGPL-3.0-or-later) and permissively licensed libraries (MIT, BSD, Zlib, IJG, libpng, libtiff). Thelicensefield inpackage.jsonis the SPDX conjunction of all of them.- Every build ships the upstream notices in
dist/licenses/, with a summary innative/licenses/README.md(published asdist/licenses/README.md). If you servewvips.wasm, keep those notices with it, and point users to the corresponding source for the version you ship (the wvips git tag). That summary explains why the LGPL relinking obligation is met that way. - This software is based in part on the work of the Independent JPEG Group.
