image-size and imageinfo are both Node.js utilities designed to read image file headers and extract metadata, specifically width and height, without loading the entire image into memory. image-size is a widely adopted library that supports a broad range of modern and legacy image formats (including WebP, SVG, and HEIC) and offers both synchronous and asynchronous APIs. imageinfo is a lighter-weight alternative that focuses on speed and simplicity, primarily targeting common web formats like JPEG, PNG, and GIF, often providing a streamlined interface for quick metadata extraction. Both tools solve the problem of validating asset dimensions during build times or server-side processing without the overhead of full image decoding.
When building backend services, build tools, or asset pipelines in Node.js, you often need to know an image's width and height without decoding the entire file. Loading a 10MB image just to read its header is wasteful. image-size and imageinfo both solve this by reading specific bytes from the file stream. However, they differ in format support, API design, and maintenance momentum. Let's compare how they handle real-world engineering tasks.
image-size supports a wide array of formats, including modern web standards and some proprietary types.
// image-size: Supports many formats out of the box
const sizeOf = require('image-size');
try {
const dimensions = sizeOf('path/to/image.webp');
console.log(dimensions.width, dimensions.height);
} catch (e) {
console.error('Unsupported format or corrupt file');
}
imageinfo focuses on the most common web formats to keep the logic lean.
// imageinfo: Focused on core formats
const imageinfo = require('imageinfo');
const info = imageinfo.checkBuffer(buffer);
if (info) {
console.log(info.width, info.height, info.format);
} else {
console.log('Unknown format');
}
image-size offers both synchronous and asynchronous methods.
// image-size: Async usage with Promises
const sizeOf = require('image-size');
sizeOf('path/to/image.png', (err, dimensions) => {
if (err) throw err;
console.log(`${dimensions.width}x${dimensions.height}`);
});
// Or with promises in newer versions
const dimensions = await sizeOf('path/to/image.png');
imageinfo is designed to work directly with buffers or strings.
// imageinfo: Requires manual buffer loading
const fs = require('fs');
const imageinfo = require('imageinfo');
const buffer = fs.readFileSync('path/to/image.png');
const info = imageinfo.checkBuffer(buffer);
if (info) {
console.log(`${info.width}x${info.height}`);
}
image-size throws exceptions when it encounters invalid files or unsupported types.
try/catch blocks, ensuring errors aren't silently ignored.// image-size: Throws on error
try {
const dimensions = sizeOf('corrupt.jpg');
} catch (err) {
// Handle specific error types
console.error('Failed to read dimensions:', err.message);
}
imageinfo typically returns null or undefined if detection fails.
// imageinfo: Returns null on failure
const info = imageinfo.checkBuffer(buffer);
if (!info) {
// Must manually handle failure case
console.warn('Could not determine image info');
return;
}
console.log(info.width);
image-size has a few dependencies to handle different format parsers.
# image-size: Standard install
npm install image-size
imageinfo is often a single-file module with zero dependencies.
# imageinfo: Lightweight install
npm install imageinfo
You need to ensure uploaded avatars are square and under a certain resolution.
image-sizeimage-size handles these gracefully.// image-size: Handle diverse uploads
const dimensions = sizeOf(req.file.buffer);
if (dimensions.width !== dimensions.height) {
return res.status(400).send('Image must be square');
}
You are generating srcset attributes for a blog during build time.
imageinfo// imageinfo: Fast build script
const buffer = fs.readFileSync(`./assets/${file}`);
const info = imageinfo.checkBuffer(buffer);
if (info) {
generateSrcSet(info.width);
}
You are processing images from a remote URL stream without saving to disk.
image-size// image-size: Stream friendly
const request = require('request');
const sizeOf = require('image-size');
request(url).on('response', function (response) {
sizeOf(response, function (err, dimensions) {
console.log(dimensions);
});
});
| Feature | image-size | imageinfo |
|---|---|---|
| Format Support | 🌐 Broad (WebP, SVG, HEIC, etc.) | 📄 Core (JPEG, PNG, GIF) |
| API Input | 📂 Path, Buffer, or Stream | 📦 Buffer or String |
| Execution | ⚡ Sync & Async | 🔄 Sync (Buffer check) |
| Error Style | 🛑 Throws Exceptions | ⚠️ Returns Null |
| Dependencies | 📦 Moderate | 🍃 Zero/Minimal |
| Maintenance | ✅ Active | ⚠️ Check Status |
Think in terms of format risk and integration complexity:
image-size. The broad format support prevents crashes when users upload unexpected file types.imageinfo. If you control the input (e.g., internal assets), the lighter weight is advantageous.image-size has better native support for non-blocking operations.Both libraries solve the same fundamental problem efficiently. image-size is the robust, general-purpose tool for production apps facing the open web. imageinfo is the scalpel for specific, controlled tasks where every kilobyte counts.
Choose image-size if your project requires support for a wide variety of image formats beyond the basics, such as WebP, SVG, or HEIC, or if you need both synchronous and asynchronous API options. It is the safer bet for long-term maintenance given its larger community footprint and frequent updates, making it ideal for build tools, CMS backends, or asset pipelines where format diversity is common. The trade-off is a slightly larger dependency footprint compared to minimalistic alternatives, but the reliability and format coverage usually justify this in production environments.
Choose imageinfo if you need a minimal, fast solution for standard web formats (JPEG, PNG, GIF) and prefer a straightforward, callback-style or promise-based interface without extra configuration. It is well-suited for lightweight microservices, simple upload validators, or scripts where minimizing dependencies is a priority and exotic image formats are not expected. However, verify its current maintenance status before adoption, as smaller utilities in this space sometimes receive less frequent updates than broader ecosystem tools.
Fast, lightweight NodeJS package to get dimensions of any image file or buffer.
npm install image-size
# or
yarn add image-size
# or
pnpm add image-size
Best for streams, network requests, or when you already have the image data in memory.
import { imageSize } from 'image-size'
// or
const { imageSize } = require('image-size')
const dimensions = imageSize(buffer)
console.log(dimensions.width, dimensions.height)
Best for local files. Returns a promise.
import { imageSizeFromFile } from 'image-size/fromFile'
// or
const { imageSizeFromFile } = require('image-size/fromFile')
const dimensions = await imageSizeFromFile('photos/image.jpg')
console.log(dimensions.width, dimensions.height)
Note: Reading from files has a default concurrency limit of 100
To change this limit, you can call the setConcurrency function like this:
import { setConcurrency } from 'image-size/fromFile'
// or
const { setConcurrency } = require('image-size/fromFile')
setConcurrency(123456)
v1.x of this library had a sync API, that internally used sync file reads.
This isn't recommended because this blocks the node.js main thread, which reduces the performance, and prevents this library from being used concurrently.
However if you still need to use this package syncronously, you can read the file syncronously into a buffer, and then pass the buffer to this library.
import { readFileSync } from 'node:fs'
import { imageSize } from 'image-size'
const buffer = readFileSync('photos/image.jpg')
const dimensions = imageSize(buffer)
console.log(dimensions.width, dimensions.height)
Useful for quick checks.
npx image-size image1.jpg image2.png
If the target file/buffer is an HEIF, an ICO, or a CUR file, the width and height will be the ones of the largest image in the set.
An additional images array is available and returns the dimensions of all the available images
import { imageSizeFromFile } from 'image-size/fromFile'
// or
const { imageSizeFromFile } = require('image-size/fromFile')
const { images } = await imageSizeFromFile('images/multi-size.ico')
for (const dimensions of images) {
console.log(dimensions.width, dimensions.height)
}
import url from 'node:url'
import http from 'node:http'
import { imageSize } from 'image-size'
const imgUrl = 'http://my-amazing-website.com/image.jpeg'
const options = url.parse(imgUrl)
http.get(options, function (response) {
const chunks = []
response
.on('data', function (chunk) {
chunks.push(chunk)
})
.on('end', function () {
const buffer = Buffer.concat(chunks)
console.log(imageSize(buffer))
})
})
import { disableTypes } from 'image-size'
// or
const { disableTypes } = require('image-size')
disableTypes(['tiff', 'ico'])
If the orientation is present in the JPEG EXIF metadata, it will be returned by the function. The orientation value is a number between 1 and 8 representing a type of orientation.
import { imageSizeFromFile } from 'image-size/fromFile'
// or
const { imageSizeFromFile } = require('image-size/fromFile')
const { width, height, orientation } = await imageSizeFromFile('images/photo.jpeg')
console.log(width, height, orientation)
Partial File Reading
SVG Limitations
File Access
setConcurrency()Buffer Requirements
MIT
not a direct port, but an attempt to have something like dabble's imagesize as a node module.