@wasmedia/wimagemagick
v0.4.0
Published
ImageMagick v7 compiled to WebAssembly for browsers, with CLI and programmatic APIs
Maintainers
Readme
wimagemagick
A feature-complete ImageMagick build with all modern dependencies, compiled for WASM so it can be easily run in a modern browser.
Install
npm install @wasmedia/wimagemagickimport { initWImageMagick } from '@wasmedia/wimagemagick';
const wim = await initWImageMagick();
const img = wim.Image.fromBuffer(bytes);
const jpeg = img.fit(1600, 1600).quality(85).toBuffer('JPEG');
img.dispose();The package ships the .wasm (about 15 MB, 5 MB gzipped) next to its JS, and
loads it relative to the module, so a bundler that copies assets referenced by
new URL(..., import.meta.url) needs no configuration. docs/api.md
has the full API, including the Web Worker entry
(@wasmedia/wimagemagick/worker). The WASM statically links ImageMagick and
several LGPL libraries; their licences are in dist/licenses/.
Try it without installing at magick.wasmedia.org.
File mode
executeFiles() runs a command over files instead of buffers: OPFS file
handles in a Web Worker, host paths under Node. The files are mounted through
wopfs rather than copied into memory, which
halves peak memory on a large image (640 → 315 MiB on a 24-megapixel TIFF):
const r = await wim.executeFiles('shot.cr2 -resize 50% shot.jpg',
[{ name: 'shot.cr2', file: fileHandle }], { outputDir: dirHandle });See File mode. wopfs (MIT) is loaded only when file mode is first used.
Format & Feature Scope
- Excluded: Ghostscript-based features (PDF rendering), FFmpeg-based features (video)
- Included: As many image formats as practical, specifically:
- Common raster, read and write: JPEG, PNG, WebP, TIFF, GIF, BMP, AVIF, JXL, JP2/J2K
- HEIC/HEIF (via libheif) — decode only; encoding would need x265
- RAW camera formats (via LibRaw) — decode only; the common ones are detected from their headers, see Reading RAW files
- Other formats as practical to cross-compile
docs/building.md has the verified format matrix and the list of delegates
that are deliberately absent.
Technical Requirements
- ImageMagick version: Always target the current stable release (currently v7)
- API surface: Both CLI-style interface (pass command strings) and C API (MagickWand/MagickCore)
- JS wrapper: High-level JS wrapper on top of the C bindings, plus CLI-style command execution
- Toolchain: Open to any practical WASM toolchain (Emscripten is the likely choice)
- Output: Both a single
.wasm+ JS glue bundle and an npm-distributable package - Bundle size: Large binaries are acceptable if necessary to support the full format set
- File I/O: Support both Emscripten virtual filesystem (MEMFS) and direct
ArrayBuffer/Blobpassing - Web Workers: Should support running off the main thread
- Distribution: Open source, published to npm as
@wasmedia/wimagemagick - Browser support: Chrome and Safari at minimum
- Build: Single-threaded + SIMD — works on any site without special headers
Prior Art
| Project | Status | IM Version | Delegates | Threading/SIMD | API Style | |---------|--------|------------|-----------|----------------|-----------| | @imagemagick/magick-wasm | Active, ~853 stars | v7 (current) | Rich (HEIF, WebP, RAW, JXL, EXR) | None | OOP TypeScript only | | WASM-ImageMagick | Abandoned (2023) | v7 (~2019 era) | Minimal (JPEG, PNG, TIFF, GIF) | None | CLI strings only | | magickwand.js | Active, ~91 stars | v7 (current) | Rich (HEIF, WebP, EXR) | Partial async workers | Full Magick++ OOP |
Gaps wimagemagick fills:
- No project offers both CLI-style and programmatic API
- AVIF support is absent from all
Build-on opportunity: dlemstra's Magick.Native already cross-compiles ImageMagick v7 + rich delegates to WASM via Emscripten. It could serve as a foundation for the native build, with wimagemagick adding threading/SIMD builds, CLI interface, and the JS wrapper layer on top.
