npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@walujanle/image-converter-wasm

v1.0.0

Published

Rust WebAssembly image converter for browser and Node.js runtimes.

Readme

image-converter-wasm

Rust WebAssembly image converter for browser and Node.js runtimes.

License: AGPL-3.0-only

This package converts images entirely in memory. Input and output are Uint8Array values; the host application owns file picking, downloads, uploads, caching, and any filesystem work.

Installation

npm install @walujanle/image-converter-wasm

Features

  • Format-split WASM modules: JPEG, PNG, WebP, and AVIF are separate WASM binaries. Only the selected output codec is loaded.
  • ESM and CommonJS entries: Use import or require from the package root.
  • Browser and Node.js support: Browser/bundler builds use adjacent WASM asset URLs. Node.js loads the packaged WASM bytes directly.
  • Supported input: jpg, jpeg, png, webp, heic, heif, avif.
  • Supported output: JPEG, PNG, WebP, AVIF.
  • HEIC/HEIF decode-only support: HEIC/HEIF can be converted from, but not encoded to.
  • Metadata extraction: EXIF, XMP, IPTC, and ICC extraction from in-memory bytes.
  • Metadata preservation: keepMetadata enables EXIF/XMP/IPTC preservation where the output container supports it. ICC color profiles may be retained for color fidelity when available.
  • Crop and resize: Percent crop, aspect-ratio-aware resize, and smart filter selection.
  • Input hardening: Size, dimension, extension, and magic-byte validation run before decode.
  • Progress callback: convertImageWithInfo can report stage-based progress.

Quick Start

ESM

import { convertImage, init } from '@walujanle/image-converter-wasm';

await init({ preload: ['Jpeg'] });

const input = new Uint8Array(await file.arrayBuffer());
const output = await convertImage(input, '.PNG', {
  format: 'Jpeg',
  quality: 82,
  resize: true,
  targetWidth: 1600,
  resizeLockAspectRatio: true,
  keepMetadata: true,
});

const blob = new Blob([output], { type: 'image/jpeg' });

CommonJS

const fs = require('fs');
const { convertImage, init } = require('@walujanle/image-converter-wasm');

(async () => {
  await init();

  const input = new Uint8Array(fs.readFileSync('photo.png'));
  const output = await convertImage(input, 'png', {
    format: 'Jpeg',
    quality: 85,
  });

  fs.writeFileSync('photo.jpg', output);
})();

API

init(options?)

Initializes wrapper configuration and optionally preloads format modules.

type OutputFormat = 'Jpeg' | 'Png' | 'WebP' | 'Avif';
type WasmSource = string | URL | Response | ArrayBuffer | ArrayBufferView | WebAssembly.Module;

interface InitOptions {
  wasmSources?: Partial<Record<Lowercase<OutputFormat>, WasmSource>>;
  preload?: OutputFormat[];
}
  • wasmSources: Overrides the default WASM source per format. Use this when your framework requires WASM files to be served from a public/static directory.
  • preload: Eagerly initializes selected output modules instead of waiting for first conversion.

You can also pass one direct WASM source to init(...); it becomes the default source for every format.

convertImage(fileBytes, ext, options)

Converts one image buffer and returns encoded bytes as Uint8Array.

interface ConvertOptions {
  format: OutputFormat;
  quality?: number;
  pngCompressed?: boolean;
  lossless?: boolean;
  resize?: boolean;
  targetWidth?: number;
  targetHeight?: number;
  resizeLockAspectRatio?: boolean;
  crop?: boolean;
  cropTop?: number;
  cropBottom?: number;
  cropLeft?: number;
  cropRight?: number;
  keepMetadata?: boolean;
}

Notes:

  • quality defaults to 75 and applies to JPEG, lossy WebP, and AVIF.
  • lossless applies to WebP.
  • pngCompressed enables higher PNG compression.
  • Crop values are percentages from 0 to 100.
  • Extensions are normalized, so PNG, .png, and png are accepted when the bytes match the format.

convertImageWithInfo(fileBytes, ext, options, onProgress?)

Converts one image buffer and returns bytes plus final dimensions.

interface ConversionResult {
  bytes: Uint8Array;
  width: number;
  height: number;
}
const result = await convertImageWithInfo(input, 'webp', {
  format: 'Avif',
  quality: 70,
}, (progress) => {
  console.log(Math.round(progress * 100));
});

The progress callback receives values from 0 to 1. Progress is stage-based, not a codec-internal byte counter.

getImageDimensions(fileBytes, ext, format?)

Returns image dimensions without running a conversion.

interface ImageDimensions {
  width: number;
  height: number;
}

extractMetadata(fileBytes, ext, format?)

Extracts embedded metadata from an in-memory image buffer.

interface ImageMetadata {
  exif?: number[] | null;
  xmp?: number[] | null;
  iptc?: number[] | null;
  icc?: number[] | null;
}

getProjectVersion(format?)

Returns the embedded project version string from the loaded WASM module.

const version = await getProjectVersion(); // "v1.0.0"

Metadata Support Matrix

This matrix describes output preservation during conversion when keepMetadata: true.

| Output Format | EXIF | XMP | IPTC | ICC | | ------------- | ---- | --- | ---- | --- | | JPEG | Yes | Yes | Yes | Yes | | PNG | Yes | Yes | Yes | Yes | | WebP | Yes | Yes | No | Yes | | AVIF | Yes | Yes | No | No |

Additional details:

  • ICC may be retained independently for color profile fidelity.
  • AVIF input can expose ICC during metadata extraction when the source has an ISOBMFF colr profile box, but AVIF output does not currently embed ICC.
  • HEIC output is not supported.

Runtime And Bundler Notes

Browser And Bundlers

The ESM wrapper loads format modules dynamically and passes each generated index_bg.wasm URL to the wasm-bindgen initializer. In many bundlers this works without extra configuration.

If your framework does not serve WASM assets from dependencies, copy the needed files from the package formats/<format>/esm/index_bg.wasm paths into your app's public/static assets and pass explicit URLs:

await init({
  wasmSources: {
    jpeg: '/wasm/image-converter/jpeg/index_bg.wasm',
    png: '/wasm/image-converter/png/index_bg.wasm',
    webp: '/wasm/image-converter/webp/index_bg.wasm',
    avif: '/wasm/image-converter/avif/index_bg.wasm',
  },
});

Browser conversions should run in browser-capable code paths. For SSR frameworks, call the browser ESM API from client-side components, client-only hooks, or a web worker.

Node.js ESM

No bundler configuration is required in Node.js. The wrapper reads packaged WASM bytes from disk.

import { init, convertImage } from '@walujanle/image-converter-wasm';

await init();
const output = await convertImage(input, 'png', { format: 'Jpeg' });

Node.js CommonJS

const { init, convertImage } = require('@walujanle/image-converter-wasm');

(async () => {
  await init();
  const output = await convertImage(input, 'png', { format: 'Jpeg' });
})();

Next.js, Nuxt, SvelteKit, Astro, React, Vue

Use the browser API only from client-side code when the conversion is meant to run in the browser. If the framework cannot resolve package WASM assets automatically, use wasmSources with public/static URLs as shown above.

Node runtime code can use the Node.js ESM or CommonJS examples. Edge runtimes are not a documented target for this package.

License

This package is licensed as AGPL-3.0-only.

The distributed WASM binaries include AGPL/commercial-licensed dependencies such as heic and zenwebp. Applications distributing this package or using it over a network must comply with AGPL-3.0-only obligations or have a separate compatible licensing path.