High-quality, high-performance image processing library built in C. Decodes JPEG / PNG / WebP / AVIF / GIF / HEIC and encodes to WebP / AVIF / PNG with Lanczos-3 resizing. Works with Node.js, Bun, and Deno via FFI — no build tools required.
npm: zenpix (Node / Bun / Deno, native) · zenpix-wasm (browser / Cloudflare Pages)
Node.js / Bun (server-side)
npm install zenpixESM only. Add
"type": "module"to yourpackage.json. CommonJS (require) is not supported.
Deno:
import { decode, encodeAvif } from "npm:zenpix/deno";
// requires --allow-ffi flagBrowser / Cloudflare Pages (WASM)
npm install zenpix-wasmSee Browser (WASM) below.
# native
npx zenpix --version
npm list zenpix
# wasm
npm list zenpix-wasmimport { decode, resize, encodeAvif, convert } from "zenpix";
import { readFileSync, writeFileSync } from "fs";
// decode → resize → AVIF
const image = decode(readFileSync("photo.jpg"));
const resized = resize(image, { width: 1920, height: 1080, fit: "cover" });
const avif = encodeAvif(resized, { quality: 60, threads: 4 });
if (avif) writeFileSync("output.avif", avif);
// one-liner pipeline
const result = convert(readFileSync("photo.jpg"), {
resize: { width: 1920, height: 1080, fit: "cover" },
encode: { format: "avif", quality: 60 },
});
if (result) writeFileSync("output.avif", result);CLI — no install needed:
npx zenpix photo.jpg # → photo.avif
npx zenpix *.jpg --out-dir ./avif/ --threads 4
npx zenpix icon.jpg favicon.png --remove-bg --round-corners fullzenpix encodes AVIF using YUV 4:4:4 (full chroma, no subsampling). Sharp defaults to YUV 4:2:0, which discards 75% of chroma information. For illustration and character art with saturated colours and fine gradients, the difference is visible at the same quality setting. Alpha channels are always encoded losslessly.
| Sharp (quality=60) | zenpix (quality=60) |
|---|---|
![]() |
![]() |
Pastel beach illustration. Sharp produces a smaller file by discarding subtle tonal nuances; zenpix retains them at a slightly larger size.
On low-core VPS environments (2–4 vCPUs), zenpix outperforms Sharp on complex illustration and character content by 1.3–1.6× in wall-clock time.
| Fixture | FHD ratio | WQHD ratio | 4K ratio |
|---|---|---|---|
| Character illustration | 1.43× | 1.35× | 1.29× |
| Oil-paint landscape | 1.62× | 1.45× | 1.63× |
ratio = Sharp ÷ zenpix median (>1 means zenpix is faster). VPS: Ubuntu, 2 vCPU. Pipeline: PNG → resize → AVIF (quality=60, speed=6). Full benchmark →
- Decode: JPEG / PNG / WebP / AVIF / GIF (first frame) / HEIC·HEIF (macOS & Linux)
- Resize: Lanczos-3, SIMD optimized (NEON/SSE2), fit modes (stretch / contain / cover)
- Encode: WebP / AVIF (per-call
threadsoption) / PNG - Pipeline:
convert()— decode → crop → resize → encode in one call - CLI:
npx zenpixwith batch, stdin/stdout support - Background removal:
removeBackground/roundCorners/flattenBackground
| Runtime | macOS arm64 | macOS x64 | Linux x64 | Linux arm64 | Windows x64 |
|---|---|---|---|---|---|
| Node.js 18+ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Bun | ✅ | ✅ | ✅ | ✅ | ✅ |
| Deno 2.x | ✅ | ✅ | ✅ | ✅ | ✅ |
zenpix-wasm encodes AVIF entirely in the browser — no server required. It uses the same libavif + libaom as the native build, compiled to WebAssembly via Emscripten.
When to use which package:
| Use case | Package |
|---|---|
| Node.js / Bun / Deno server | zenpix (native, fastest) |
| Browser / Cloudflare Pages static JS | zenpix-wasm |
| Cloudflare Workers Free | Not supported (10ms CPU limit) |
Quick example:
import { createAvifEncoder } from "zenpix-wasm";
const enc = await createAvifEncoder();
// pixels: Uint8Array of raw RGBA (width × height × 4)
const avif = enc.encode(pixels, width, height, { quality: 60, speed: 10 });
if (avif) {
const blob = new Blob([avif], { type: "image/avif" });
}
enc.dispose();SIMD detection (recommended):
const simdSupported = WebAssembly.validate(new Uint8Array([
0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11
]));
const { createAvifEncoder } = simdSupported
? await import("zenpix-wasm/simd") // Chrome 91+ / Firefox 89+ / Safari 16.4+
: await import("zenpix-wasm");Vite — serve the .wasm file via URL:
import wasmUrl from "zenpix-wasm/dist/avif.wasm?url";
import { createAvifEncoder } from "zenpix-wasm";
const enc = await createAvifEncoder(wasmUrl);See wasm/README.md for full documentation.
MIT © 2026 Tsukasa Tsukimura
Uses: libjpeg-turbo, zlib, libpng, libwebp, libavif, libaom, libheif — see THIRD_PARTY_LICENSES.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
npm run build # TypeScript → js/dist/See docs/reference/environments.md for local build details.

