Free and open source · zero runtime dependencies

Image codecs and low-memory raster processing in strict TypeScript.

PureJsImage combines portable image codecs and native scientific raster processing in one strict TypeScript engine for Node.js and modern browsers. Bounded rows and tiles reduce memory pressure where formats permit it, while the same API runs across servers, browsers, serverless, edge, and restricted deployments.

14stable ordinary codecsmanifest-generated supportJPEG, PNG, WebP, BMP, TIFF, GIF, ICO, JPEG 2000 / JP2, AVIF, JPEG XL, Radiance HDR / RGBE, QOI, Netpbm and PFM, TGA / TARGA. Experimental HEIF/HEIC remains a separate explicit import.
33scientific readers6 format familiesThe package has more readers than the five formats in the live browser explorer.
84.7%less peak RSS than Jimp181.8 MiB vs 1189.1 MiBCurrent 2026-08-24 isolated-process result for the same 24-megapixel northstar photo pipeline and one environment fingerprint.
6stable medium/large scientific benchmark rows13 representative workloads validated, 6 under the 10% CV publication thresholdCorrectness and startup rows stay on the baseline profile (43 validated reader workflows, 43 contract workloads). Representative medium/large performance comes from the separate scaling profile: 13 validated workloads, 6 under the 10% CV publication threshold.

Use each info button for the source, workflow, and measurement details.

npm install purejsimage
Runtime examples
Choose a runtime
import { createImageLibrary } from
  'purejsimage/browser'
import { jpegCodec } from
  'purejsimage/codecs/jpeg'

const images = createImageLibrary([jpegCodec])
const image = await images.open(file)

const output = await image
  .autoOrient()
  .resize({ width: 1200 })
  .jpeg({ quality: 80 })
  .toBlob()
import { createImageLibrary } from
  'purejsimage'
import { jpegCodec } from
  'purejsimage/codecs/jpeg'

const images = createImageLibrary([jpegCodec])
const image = await images.open('input.jpg')

await image
  .autoOrient()
  .resize({ width: 1200 })
  .jpeg({ quality: 80 })
  .toFile('output.jpg')
import { createImageLibrary } from 'purejsimage'
import { jpegCodec } from
  'purejsimage/codecs/jpeg'

const images = createImageLibrary([jpegCodec])

export const handler = async (input: Buffer) =>
  (await images.open(input))
    .autoOrient()
    .resize({ width: 1200, withoutEnlargement: true })
    .jpeg({ quality: 80 })
    .toBuffer()
strict TypeScriptimmutable pipelinetyped failures

Measured performance across common image workflows.

The 2026-08-24 profile compares default PureJsImage and its explicit JPEG, PNG, and WebP WASM accelerators with Jimp, Sharp, Sharp single-thread, image-js, and jSquash on the same inputs. Each engine runs in isolation and every displayed output is validated before timing is admitted.

122validated passes
25explicit unsupported results
0invalid outputs or errors

JPEGPNGWebPTIFFAVIF

v24.16.0 · Linux 6.17.0-41-generic · x64 · Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz · 2026-08-24Methodology · Readable report · JSON

PureJsImage Lab.

The first app built on the scientific platform: a local-first browser workbench for electron microscopy files. It is still in progress.

Open PureJsImage Lab

Browse a multi-gigabyte whole-slide image without converting it.

Whole-slide pathology is one example: the browser reads the original Aperio SVS pyramid through HTTP Range and decodes only the visible tiles.

Open the live demo
PureJsImage whole-slide viewer showing a pathology tissue section beside live measurements for a 2.12 GB Aperio SVS slide
Original pyramid tiles in the browserThe measured session shown fetched 11.4 MiB, or 0.562% of the 2.12 GB source, while panning and zooming a 6,719.9 megapixel slide.
HTTP RangeWeb WorkerNo tile serverNo sidecar index

A codec-native resize path without a full-frame bitmap.

The baseline JPEG path demonstrates the larger memory model: it retains one MCU row, pushes crop and resize toward decode, and releases source rows when they can no longer affect the output.

1 MCU rowretained at the decoder boundary
  • 01Decode useful MCU rowsSkip pixels outside the requested region.
  • 02Resize through a row ringReuse a bounded set of typed buffers.
  • 03Encode and releaseAvoid duplicate full-frame boundaries.

Scientific rasters, not just everyday photos.

TIFF demo and details →

This table covers TIFF, OME microscopy, whole-slide pathology, and geospatial rasters. It separates documented features from a 106-file test of decode coverage and output.

The main columns on a phone. The full TIFF table is still on this page below.

  • PureJsImage

    Strict TypeScript

    Pure TypeScript
    Yes
    Runtime dependencies
    None
    Browser support
    Yes
    Native addon
    No
    Scientific readers
    Yes
    Bounded memory model
    Yes
  • GeoTIFF.js

    Pure JavaScript

    Pure TypeScript
    Yes
    Runtime dependencies
    JavaScript package
    Browser support
    Yes
    Native addon
    No
    Scientific readers
    Yes
    Bounded memory model
    Yes
  • UTIF.js (utif2)

    Pure JavaScript

    Pure TypeScript
    Yes
    Runtime dependencies
    JavaScript package
    Browser support
    Yes
    Native addon
    No
    Scientific readers
    Partial
    Bounded memory model
    No
  • image-js/tiff

    Pure JavaScript

    Pure TypeScript
    Yes
    Runtime dependencies
    JavaScript package
    Browser support
    Yes
    Native addon
    No
    Scientific readers
    Yes
    Bounded memory model
    No
  • image-js

    Pure JavaScript

    Pure TypeScript
    Yes
    Runtime dependencies
    JavaScript package
    Browser support
    Yes
    Native addon
    No
    Scientific readers
    Partial
    Bounded memory model
    No
  • Jimp

    Pure JavaScript

    Pure TypeScript
    Yes
    Runtime dependencies
    JavaScript package
    Browser support
    Yes
    Native addon
    No
    Scientific readers
    No
    Bounded memory model
    No
  • Sharp / libvips

    Native wrapper

    Pure TypeScript
    No
    Runtime dependencies
    Native addon
    Browser support
    No
    Native addon
    Yes
    Scientific readers
    Partial
    Bounded memory model
    Partial
Full comparison matrix
LibraryBrowserBigTIFFTilesRegionScientific rasterOME / WSIDecode coverage
PureJsImagebenchmark snapshot · 3be4530 · Strict TypeScriptYesYesYesYesYesYes104/106 decoded57 exact · 47 pixel mismatches2 oracle-unavailable cases
GeoTIFF.js3.0.5 · Pure JavaScriptYesPartialYesYesYesNo84/106 decoded32 exact · 52 pixel mismatches11 unsupported · 7 errors · 2 oracle-unavailable cases · 2 crashes
UTIF.js (utif2)4.1.0 · Pure JavaScriptYesNoYesNoPartialNo74/106 decoded49 exact · 25 pixel mismatches28 errors · 2 oracle-unavailable cases · 2 timeouts · 3 crashes
image-js/tiff7.1.3 · Pure JavaScriptYesNoYesNoYesNo41/106 decoded27 exact · 14 pixel mismatches51 unsupported · 12 errors · 2 oracle-unavailable cases
image-js1.7.0 · Pure JavaScriptYesNoYesNoPartialNo39/106 decoded33 exact · 6 pixel mismatches51 unsupported · 14 errors · 2 oracle-unavailable cases
Jimp1.6.0 · Pure JavaScriptYesNoYesNoNoNo74/106 decoded49 exact · 25 pixel mismatches28 errors · 2 oracle-unavailable cases · 2 timeouts · 3 crashes
Sharp / libvips0.35.3 · Native wrapperNoPartialYesPartialPartialNoNot run

Oracle unavailable is not an engine failure: the independent Sharp/ImageMagick ground-truth path could not decode the same two fixtures for every measured engine. PureJsImage's 47 non-exact decodes comprise 38 at or above 40 dB PSNR, 6 from 20 to below 30 dB, and 3 below 10 dB, derived from recorded RMSE. Jimp uses utif2 for TIFF internally, so its matching aggregate outcomes are expected.

Measured 2026-08-13 with v24.16.0 on linux/x64. Methods, caveats, versions, and sources.

One portable engine. Register only the codecs you need.

Read the API
01 / MEMORY

Documented memory classes

JPEG MCU rows, PNG scanlines, TIFF strips, and experimental HEIF tiles use bounded paths where implemented. Full-frame fallbacks are identified and benchmarked separately.

02 / SAFETY

Input and allocation validation

Dimensions, allocation budgets, box extents, truncation, and entropy reads are checked before allocation or indexing.

03 / PORTABILITY

Portable reference, optional acceleration

The default codecs require no native addons, WASM, GPU backend, external binaries, or runtime dependencies. Shipped JPEG, PNG, and WebP WASM accelerators use separate explicit imports.

The acceleration roadmap defines how large jobs may progressively use optional WASM or WebGPU providers without changing the default package or output semantics.

Questions about PureJsImage.

These answers describe the default package. The codec and reader documentation lists exact support boundaries.

What is PureJsImage?

PureJsImage is an image codec and raster-processing library written in strict TypeScript. It runs in Node.js and modern browsers and has no runtime dependencies.

Does PureJsImage work in both Node.js and web browsers?

Yes. The shared codec, pipeline, transform, source, sink, and public APIs support Node.js 22 or later and modern browsers. Browser applications use File, Blob, ArrayBuffer, Uint8Array, fetched bytes, or an ImageSource instead of local path strings.

Which image formats does PureJsImage support?

PureJsImage supports JPEG, PNG, WebP, BMP, TIFF, GIF, ICO, JPEG 2000, AVIF, JPEG XL, Radiance HDR, QOI, Netpbm, and TGA. Read, write, and format-subset support varies, so use the codec matrix for exact boundaries.

Can PureJsImage read scientific and geospatial image data?

Yes. Explicit reader imports cover microscopy, whole-slide pathology, medical imaging, astronomy, structural biology, hyperspectral, geospatial, and multidimensional array formats. Readers preserve native numeric samples where the format and API permit it.

Does PureJsImage load WebAssembly or native code by default?

No. The default package uses strict TypeScript reference codecs and does not load native addons, external binaries, or WebAssembly. Optional JPEG, PNG, and WebP WebAssembly accelerators require explicit imports and registration.

How does PureJsImage reduce memory use?

PureJsImage uses bounded rows, tiles, regions, source reads, and compact coefficient storage where each format permits them. Full-frame fallbacks are explicit and benchmarked separately.

Install the package and register the required codecs.

PureJsImage is free and open source under the MIT license. The root API does not load codec implementations automatically.