image-size

Fast, zero-dependency Node.js library that reads image width and height straight from file or buffer headers.

Library
npm
v2.0.4
2,228 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
57 /100 Fair
Development Activity 40
Maintenance 24
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
69 /100 Good
Architecture 80
Code Quality 78
Innovation 72
Learning Curve 45

image-size is a lightweight Node.js package for detecting the dimensions of an image without decoding the full file. It parses just enough of an image’s header bytes to return width, height, and (for JPEG) EXIF orientation, which keeps memory use minimal even for large images.

It ships with zero runtime dependencies, dual ESM/CommonJS builds with bundled TypeScript types, a synchronous buffer-based API (imageSize), an async file-based API (imageSizeFromFile) with a bounded concurrency queue to avoid exhausting file descriptors, and a small CLI for quick checks from the terminal. Detection covers 19+ formats including PNG, JPEG, GIF, WebP, SVG, TIFF, HEIF/AVIF, ICO, and PSD, with multi-image formats (ICO, CUR, HEIF) returning every embedded image’s dimensions.

What You Get

  • A synchronous imageSize(buffer) function that returns { width, height, type } from an in-memory Uint8Array/Buffer
  • An async imageSizeFromFile(path) helper with a configurable concurrency queue for reading many files without hitting descriptor limits
  • Support for 19+ image formats (PNG, JPEG, GIF, WebP, SVG, TIFF, BMP, ICO, CUR, PSD, HEIF/AVIF, JPEG-XL, KTX, DDS, TGA, PNM, and more) behind one consistent API
  • Multi-image results for container formats (ICO, CUR, HEIF) via an images[] array, plus JPEG EXIF orientation when present
  • A bundled CLI (npx image-size file.jpg) for one-off dimension checks from the terminal
  • Dual ESM/CommonJS builds with bundled TypeScript declarations and zero runtime dependencies

Common Use Cases

  • Validating uploaded image dimensions server-side before accepting or resizing a file
  • Generating responsive <img> width/height attributes at build time to prevent layout shift
  • Filtering or sorting a batch of images by resolution without opening each one in a full image library
  • Reading dimensions of remote images from an HTTP response buffer without saving them to disk first
  • CLI-based quick inspection of image assets during development or in CI scripts

Under The Hood

Architecture

The library is organized around three thin layers: a public entry (lib/index.ts) that re-exports from lookup.ts and types/index.ts; a detection layer (lib/detector.ts) that sniffs the first byte against a lookup map to shortlist a likely handler before falling back to a linear scan of every registered type; and a handler layer where each format (lib/types/*.ts, e.g. png.ts, svg.ts, heif.ts) implements the same IImage interface (validate, calculate) declared in interface.ts and registered in one typeHandlers Map in types/index.ts. lib/fromFile.ts adds an async file-reading façade with a bounded work queue (default concurrency 100) that reuses the same buffer-based imageSize call rather than duplicating parsing logic. This registry-of-handlers shape makes adding a format a matter of one new file plus one Map entry, and what would break if the core abstraction changed is the shared ISizeCalculationResult/IImage contract every handler and the detector depend on.

Tech Stack

package.json declares zero runtime dependencies; everything is a devDependency — Biome for combined linting and formatting, TypeScript 5.4, tsup for bundling to dual CJS/ESM output with .d.ts files per the package’s conditional exports map, ts-node and c8 for running and covering tests, typedoc for API docs generation, and glob for test fixture handling. The package manager is Yarn 4 (Berry, per .yarnrc.yml and yarn.lock), CI runs on CircleCI, and the runtime target is Node.js 16+ per the engines field.

Code Quality

Tests use Node’s native node:test runner (not a separate test framework) across specs/*.spec.ts — covering bit-reading utilities, file-handle cleanup, invalid-input handling, format edge cases, and general utilities — with fixture images under specs/images/ and c8 for coverage reporting. Each format handler raises a specific, typed error (e.g. PNG throws Invalid PNG, SVG throws Invalid SVG) rather than silently returning wrong data, and Biome enforces consistent naming and formatting across the codebase in place of a separate ESLint/Prettier setup.

What Makes It Unique

Most dimension-reading libraries stop at width and height; image-size also surfaces JPEG EXIF orientation, returns every embedded image’s size for multi-image containers (ICO, CUR, HEIF) rather than just the first, and does all of this while keeping the runtime dependency count at zero and supporting both buffer-based and queued file-based access patterns out of the box.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers