Skip to content

tsukasa-art/zenpix

Repository files navigation

zenpix

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)


Install

Node.js / Bun (server-side)

npm install zenpix

ESM only. Add "type": "module" to your package.json. CommonJS (require) is not supported.

Deno:

import { decode, encodeAvif } from "npm:zenpix/deno";
// requires --allow-ffi flag

Browser / Cloudflare Pages (WASM)

npm install zenpix-wasm

See Browser (WASM) below.


Check installed version

# native
npx zenpix --version
npm list zenpix

# wasm
npm list zenpix-wasm

Quick Start

import { 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 full

Why zenpix?

Better quality — always

zenpix 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)
sharp zenpix

Pastel beach illustration. Sharp produces a smaller file by discarding subtle tonal nuances; zenpix retains them at a slightly larger size.

Faster on VPS — for illustration content

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 →


Features

  • 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 threads option) / PNG
  • Pipeline: convert() — decode → crop → resize → encode in one call
  • CLI: npx zenpix with batch, stdin/stdout support
  • Background removal: removeBackground / roundCorners / flattenBackground

Platform Support

Runtime macOS arm64 macOS x64 Linux x64 Linux arm64 Windows x64
Node.js 18+
Bun
Deno 2.x

Browser (WASM)

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.


Documentation


License

MIT © 2026 Tsukasa Tsukimura

Uses: libjpeg-turbo, zlib, libpng, libwebp, libavif, libaom, libheif — see THIRD_PARTY_LICENSES.


For Contributors

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.

About

Fast image processing library (C + CMake)

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors