image-dimensions reads a header instead of the picture, and tells you when it cannot
Get the dimensions of an image
At a glance
- What is it?
- image-dimensions is a zero dependency JavaScript module that returns the width, height and type of JPEG, PNG, GIF, WebP, AVIF and HEIF images from a stream or a buffer. It reads as few bytes as the format allows, and it does not apply orientation.
- Who is it for?
- Adopt image-dimensions if you need image width and height in a browser, Node.js, Bun or Deno, you want zero dependencies, and you control where the bytes come from, because it deliberately does not read files and does not apply EXIF or HEIF orientation. Do not adopt it if you need broad format coverage or orientation aware dimensions, since the README names both as things image-size does better.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 35 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Reading a header, not a picture
image-dimensions does one thing: it tells you how big an image is. The README describes it as a module that works in any modern JavaScript environment, browsers, Node.js, Bun, Deno and similar, and the repository description is the same one line.
The mechanism is the interesting part. Every one of the supported formats stores its dimensions near the start of the file, in a header, so a reader that knows where to look does not need the image data at all. The README makes the efficiency point explicitly in the usage example, with a comment saying that it will only read a few bytes of the image instead of fetching the whole thing.
That is what makes the package useful on the web. A layout system that needs to reserve space for an image before it loads can read the dimensions from the first chunk of a response and lay out correctly, instead of waiting for the whole file or hard coding a ratio.
The API is two functions. imageDimensionsFromStream takes a ReadableStream of Uint8Array and returns a Promise. imageDimensionsFromData takes a Uint8Array and returns the value directly, synchronously. Both return the width, the height and a type string, or undefined when the format is not supported or the data is invalid.
The README says to prefer the stream method, and gives the reason implicitly: it reads the least amount of data, and it is the one that can stop early.
Six formats, and a stated non-goal
The supported formats are JPEG, PNG including APNG, GIF, WebP, AVIF, and HEIF including HEIC.
The ImageType value is exported and can be one of png, jpeg, gif, webp, avif, or heic. Note that the type string is heic for the HEIF family, so a HEIF container that is not HEIC still reports as heic.
The scope statement comes first in the README, before the format list, and it is blunt: supporting all kinds of image formats is a non-goal. The one exception named is JPEG XL, where pull requests are explicitly welcome.
That framing tells you how to read the package. It is not trying to be a complete image toolkit. It is trying to be a small, correct, dependency free header reader for the formats that dominate the web, with a clear door left open for one more.
The Related section points at two sibling packages, image-type for detecting the type of an image and file-type for detecting the type of a file. Those cover the neighbouring questions, which is another way of saying the scope is deliberate and narrow.
The stream API is the one to reach for first
The usage example in the README fetches a URL and reads the dimensions from the response body.
import {imageDimensionsFromStream} from 'image-dimensions';
// In this example, it will only read a few bytes of the image instead of fetching the whole thing.
const url = 'https://sindresorhus.com/unicorn';
const {body} = await fetch(url);
console.log(await imageDimensionsFromStream(body));
//=> {width: 1920, height: 1080, type: 'png'}The returned object gives three fields, width, height and type, and the example shows the shape of the result.
The Node.js variant converts a file read stream into a web stream, because the API is specified in terms of ReadableStream.
// Node.js example
import {createReadStream} from 'node:fs';
import {Readable} from 'node:stream';
import {imageDimensionsFromStream} from 'image-dimensions';
const stream = Readable.toWeb(createReadStream('unicorn.png'));
console.log(await imageDimensionsFromStream(stream));
//=> {width: 1920, height: 1080, type: 'png'}The library deliberately does not do file reading for you, which the README lists as one of its advantages over image-size: it does not include unnecessary APIs for file reading. The trade is that in Node you write two lines of glue, and in exchange the same code works in a browser.
The buffer variant, and what undefined means
If you already have the bytes, imageDimensionsFromData takes a Uint8Array and returns the result synchronously.
import {imageDimensionsFromData} from 'image-dimensions';
const data = getImage();
console.log(imageDimensionsFromData(data));
//=> {width: 1920, height: 1080, type: 'png'}The README says this method can be useful if you already have the image loaded in memory. That is a narrower case than it sounds, because if you have loaded the whole image into memory you have usually already paid the cost the library exists to avoid.
The undefined return deserves attention, because it is the case that will appear in production. Both methods return undefined if the image format is not supported or the image data is invalid. That is a single return value covering two different failures, an unsupported format and a corrupt file, and the caller cannot tell them apart from the result alone.
So the defensive pattern is to check for undefined and branch, rather than to destructure the result and hope. A pipeline that assumes every URL returns a valid image will throw on exactly the inputs that matter most, namely the ones a user uploaded and got wrong.
Orientation is not applied, which is the one surprise in the API
Both API sections carry the same note: the methods return raw pixel dimensions, and orientation, whether from EXIF or from the HEIF and AVIF irot property, is not applied.
This is the detail most likely to cause a bug that is hard to see. A photo taken in portrait on a phone is stored with pixel dimensions in wide order and a rotation flag. The module will report the stored dimensions, so a layout that reserves space using them reserves the wrong shape, and the image appears rotated or stretched once the browser applies the orientation.
The README states the limitation twice, once per method, which suggests the author considers it important. It is also listed in the comparison with image-size, where getting JPEG image orientation is named as an advantage of that package.
The same applies to the HEIF and AVIF irot property, which is the modern equivalent of the EXIF orientation tag. If your input is a HEIC photo from a phone, the number you get back is the unrotated one.
The fix is on your side, and it is not hard: read the orientation yourself and swap width and height when the value calls for a quarter turn. But you have to know to do it.
A CLI for one-off checks, and the image-size comparison
The package also ships a command line tool, since the bin field points at ./cli.js.
npx image-dimensions unicorn.png
630x400The output is the dimensions as width by height and nothing else, which makes it useful in a shell pipeline or a quick check during development.
The README has a FAQ section that compares this package with image-size, and it is the most useful part of the documentation for a decision. The advantages of image-dimensions are listed as zero dependencies, smaller size, working in non-Node.js environments like the browser, and not including unnecessary APIs for file reading. The advantages of image-size are listed as supporting more image formats and supporting getting JPEG image orientation.
That is a fair summary of the actual trade. image-dimensions wins on size, portability and dependency count. image-size wins on coverage and on orientation. There is no claim here that one is generally better, and the choice comes down to whether your inputs are the six formats listed and whether you need to handle camera orientation.
The related packages image-type and file-type cover detection, so if you need to identify a file first and then measure it, the two live next to each other in the same catalogue.
MIT licensed, ESM only, and built for a Node 18 floor
The licence is MIT, recorded in package.json and with the text in the license file at the top of the repository.
The packaging tells you a few things about who it is for. The package is type module, so it is ESM only, and the exports map has just two entries, types pointing at index.d.ts and default pointing at index.js. There is no require condition, so a CommonJS project cannot require it directly and would need a dynamic import. The engines field requires Node 18 or newer.
It also declares sideEffects as false, which tells bundlers that importing it has no side effects and the import can be dropped if none of its exports are used. For a module that only reads bytes, that is accurate and it helps tree shaking in a browser bundle.
The published files list is index.js, index.d.ts, utilities.js, a types directory and cli.js. The type definitions are a separate file rather than inline, and the test script runs xo for linting, ava for the tests and tsc against index.d.ts, so the type declarations are type checked in CI rather than trusted.
On maintenance, the repository is not archived and the last push was on 2026-09-18, with the v2.6.0 release on the same day, v2.5.1 in May 2026 and v2.5.0 in September 2025. So the project is still moving, at the pace of a small utility with a stable API and occasional format additions.
Editorial conclusion
Adopt image-dimensions if you need image width and height in a browser, Node.js, Bun or Deno, you want zero dependencies, and you control where the bytes come from, because it deliberately does not read files and does not apply EXIF or HEIF orientation. Do not adopt it if you need broad format coverage or orientation aware dimensions, since the README names both as things image-size does better. Before you wire it into a pipeline, confirm your inputs are one of the six supported formats, and if you serve photos straight from a camera, handle the orientation flag yourself because the module returns raw pixel dimensions.
Frequently asked questions
How do I install image-dimensions?
Run npm install image-dimensions. The package is an ES module with type module in package.json, requires Node 18 or newer, and has no runtime dependencies.
Which image formats does image-dimensions support?
JPEG, PNG including APNG, GIF, WebP, AVIF, and HEIF including HEIC. The exported ImageType can be one of png, jpeg, gif, webp, avif, or heic. The README says supporting all image formats is a non-goal, though pull requests for JPEG XL are welcome.
Does image-dimensions apply EXIF orientation?
No. The README notes for both methods that they return raw pixel dimensions and that orientation, whether EXIF or the HEIF and AVIF irot property, is not applied. The README lists getting JPEG image orientation as an advantage of image-size instead.
What happens if the image is not a supported format or the data is invalid?
Both imageDimensionsFromStream and imageDimensionsFromData return undefined if the image format is not supported or the image data is invalid, so callers need to check the result rather than assume an object.
How does image-dimensions differ from image-size?
The README lists the advantages of image-dimensions as zero dependencies, smaller size, working in non-Node.js environments like the browser, and not including unnecessary APIs for file reading. The advantages of image-size are listed as supporting more image formats and supporting getting JPEG image orientation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sindresorhus-image-dimensions)Was this useful?