exif-reader
A dependency-free Node.js library that decodes EXIF metadata from raw JPEG and TIFF image buffers.
Repository Health
Technical Analysis
exif-reader is a lightweight, zero-dependency library for parsing EXIF metadata out of raw JPEG and TIFF image buffers in Node.js. Given a buffer, it walks the underlying TIFF IFD structure and returns a plain JavaScript object grouped into Image, Thumbnail, Photo, GPSInfo, and Iop sections, with dates automatically converted to native Date objects.
Its tag names are generated directly from the Exiv2 project’s canonical Exif tag list rather than hand-maintained, so field names track the official specification, and a documented migration table covers any tags renamed or removed between versions. The library ships with TypeScript definitions and is defensively coded against malformed or truncated input, making it a common building block behind other image-metadata tools like jpg-stream.
What You Get
- A single function export that decodes a raw Exif/TIFF buffer into a structured JS object
- Grouped output (Image, Thumbnail, Photo, GPSInfo, Iop) matching the Exif IFD structure
- Standard-compliant tag names sourced from the Exiv2 tag reference, with a documented migration table for renamed or duplicate tags
- Bundled TypeScript type definitions covering every supported tag
- Automatic conversion of Exif date fields into native JavaScript Date objects
Common Use Cases
- Auto-rotating and geotagging user-uploaded photos in web apps
- Powering Exif extraction inside image-processing libraries like jpg-stream
- Populating searchable metadata fields in digital asset management systems
- Sorting and organizing photo libraries by capture date or GPS location
Under The Hood
Architecture
exif-reader is a single-file, purely functional module: it validates the buffer’s byte-order marker (II/MM or an Exif\0 prefix), locates the first IFD offset, then walks tag entries via readTags/readTag/readValue, recursing into Image, Thumbnail, Photo (via the ExifTag pointer), GPSInfo (via GPSTag), and Iop (via InteroperabilityTag) sub-IFDs. Tag-name resolution is data-driven off tags.js, which is itself generated by exiv2/generate.mjs from a scraped exiv2.json, decoupling the tag-mapping layer from the parsing logic. There’s no class hierarchy or dependency injection — it’s a small, self-contained monolith, so any consumer of the exported function (jpg-stream, image-processing wrappers) is directly coupled to this one parsing path.
Tech Stack
The runtime module is plain CommonJS JavaScript with zero runtime dependencies and no build step, paired with a hand-authored index.d.ts for TypeScript consumers. Development tooling includes mocha with the unexpected/unexpected-check assertion libraries (the latter adding property-based/fuzz-style test generation via chance-generators), tsd for validating the type declarations, and a small Node ESM codegen script (exiv2/generate.mjs) that regenerates tags.js and index.d.ts from the Exiv2 tag data. GitHub Actions CI runs npm install && npm test on every push and pull request.
Code Quality
Tests live under test/index.js and exercise real binary fixture files covering big-endian, little-endian, PNG-embedded, and non-ASCII Exif segments, supplemented by property-based fuzzing against random buffers to guard against crashes on malformed input. The parsing code itself is extensively defensive — nearly every read is guarded by an explicit buffer-length check that returns null rather than throwing on truncated or corrupt data. Type safety for consumers comes from the separately tested index.d.ts rather than from the source itself, which remains plain JavaScript, and no linter or formatter configuration is present in the repo.
What Makes It Unique The library’s distinguishing choice is generating its tag-name table directly from the Exiv2 project’s canonical Exif tag reference instead of hand-maintaining names the way many comparable parsers do, which keeps output field names aligned with the official spec and comes with a documented migration table for tags that were renamed, duplicated, or removed as a result. Combined with its zero-dependency footprint and heavy bounds-checking, it favors being a minimal, standards-aligned building block over exhaustive vendor-specific MakerNote support, which is why it shows up as the Exif backend inside other image-metadata tooling rather than as a full-featured standalone Exif suite.