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

@standardagents/sip

v0.12.9

Published

Small Image Processor - Ultra memory-efficient image processing for Cloudflare Workers

Readme

@standardagents/sip

Small Image Processor - Ultra memory-efficient image processing for Cloudflare Workers.

Features

  • Format Detection: Probe images for format and dimensions without decoding
  • Scanline Resize: Memory-efficient bilinear interpolation using only 2 rows at a time
  • Multi-format Input: JPEG, PNG, WebP, AVIF
  • JPEG Output: Always outputs JPEG with configurable quality
  • Size Control: Resize to target dimensions and/or file size
  • Streaming WASM (optional): DCT-scaled JPEG decoding for <1MB peak memory on any image size

Installation

pnpm add @standardagents/sip

Usage

import { sip } from '@standardagents/sip';

// Process an image
const result = await sip.process(imageBuffer, {
  maxWidth: 2048,
  maxHeight: 2048,
  maxBytes: 1.5 * 1024 * 1024, // 1.5MB target
  quality: 85,
});

console.log(result.width, result.height); // Output dimensions
console.log(result.mimeType); // 'image/jpeg'
console.log(result.originalFormat); // 'png', 'jpeg', etc.

// Get the output
const jpegBlob = new Blob([result.data], { type: 'image/jpeg' });

Probe Only

Get image info without decoding:

import { sip } from '@standardagents/sip';

const info = sip.probe(imageBuffer);
console.log(info.format); // 'jpeg' | 'png' | 'webp' | 'avif'
console.log(info.width, info.height);
console.log(info.hasAlpha);

API

sip.process(input, options)

Process an image: decode, resize, and encode to JPEG.

Parameters:

  • input: ArrayBuffer - Input image data
  • options: ProcessOptions - Processing options

Options:

  • maxWidth?: number - Maximum output width (default: 4096)
  • maxHeight?: number - Maximum output height (default: 4096)
  • maxBytes?: number - Target output size in bytes (default: 1.5MB)
  • quality?: number - JPEG quality 1-100 (default: 85)

Returns: ProcessResult

  • data: ArrayBuffer - JPEG image data
  • width: number - Output width
  • height: number - Output height
  • mimeType: 'image/jpeg' - Always JPEG
  • originalFormat: ImageFormat - Original input format

sip.probe(input)

Get format and dimensions without decoding.

Parameters:

  • input: ArrayBuffer | Uint8Array - Image data

Returns: ProbeResult

  • format: 'jpeg' | 'png' | 'webp' | 'avif' | 'unknown'
  • width: number
  • height: number
  • hasAlpha: boolean

Memory Efficiency

The library has two processing modes:

Standard Mode (Default)

Uses @jsquash/* packages for decode/encode with scanline-based resize:

  • Only 2 rows in memory during resize
  • Full image decoded to memory first
  • Works for images that fit in Worker memory (~128MB limit)

Streaming WASM Mode (Optional)

For JPEG images when WASM is built, uses ultra-efficient streaming:

  • DCT Scaling: Decode JPEG at 1/2, 1/4, or 1/8 scale directly during decompression
  • Scanline Processing: Never holds the full image in memory
  • Peak Memory: ~50KB for any image size

Memory comparison for a 25MP (6800x3900) image:

| Mode | Peak Memory | |------|-------------| | Standard (@jsquash) | ~107MB | | Streaming WASM (1/4 scale) | ~50KB |

Building WASM Module

The WASM module is optional. Without it, sip falls back to standard processing.

Prerequisites

Build

# Install Emscripten (if not already)
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk && ./emsdk install latest && ./emsdk activate latest
source ./emsdk_env.sh

# Build WASM
cd packages/sip
pnpm build:wasm

This downloads libjpeg-turbo, compiles it to WASM, and generates:

  • dist/sip.js - Emscripten loader
  • dist/sip.wasm - WebAssembly binary

Using WASM

To enable streaming mode, register the WASM loader before processing:

import { sip } from '@standardagents/sip';
import createSipModule from '@standardagents/sip/dist/sip.js';

// Register WASM loader (once at startup)
globalThis.__SIP_WASM_LOADER__ = async () => createSipModule();

// Now sip.process() will use streaming for JPEG
const result = await sip.process(jpegBuffer, { maxWidth: 2048 });

Architecture

Input → [Probe] → [Decode*] → [Resize] → [Encode*] → Output
                     ↓           ↓           ↓
              WASM: DCT     Scanline    WASM: Scanline
              Scaling       Bilinear    JPEG Encode

*When WASM is available, decode and encode process one row at a time.

License

UNLICENSED - Proprietary