Skip to main content

Core Parsing Architecture

exiftool uses a streaming, zero-copy parsing architecture designed for performance and memory efficiency.

Pipeline Architecture​

Input (File/Stream/Buffer)
│
▼
Format Detection (Magic Bytes)
│
▼
Format Parser (JPEG/PNG/WebP/AVIF-HEIF/TIFF-family RAW)
│
▼
├── EXIF/TIFF Parser ──────► IFD Walking
├── XMP Parser ───────────► XML + RDF Parsing
├── IPTC Parser ──────────► Application Record Parsing
├── ICC Profile Parser ───► Tag Decoding
├── JUMBF Parser ──────────► Box Walking + CBOR
└── MakerNote Decoder ───► Vendor tag decoding (Canon, Nikon, Sony, Olympus, Panasonic, Pentax)
│
▼
Composite Tag Computation
│
▼
Output Normalization (JSON/CSV/Tabular)

Memory Design​

  • Zero-copy: tag values are Uint8Array views into the source buffer where possible — copy out before retaining
  • Whole-buffer reads: files are read fully into memory; there is no streaming or partial-load mode
  • No subprocesses: parsing happens in-process, one read() per file, no exiftool binary involved

Format Parsers​

Each format has a dedicated parser plugin in src/format/:

FormatParserKey Features
JPEGjpeg.tsAPP1 EXIF/XMP, APP13 IPTC, APP11 JUMBF, JFIF, MPF
PNGpng.tsiTXt/tEXt/zTXt, eXIf, caBX (JUMBF)
WebPwebp.tsVP8/VP8L, EXIF/XMP in VP8X
AVIF/HEIFavif.tsISOBMFF boxes, Exif/XMP/ICC in meta
TIFF-family RAWtiff-raw.tsTIFF, DNG, CR2, NEF, ARW, ORF, RW2, PEF, ERF, DCR, SRW (read-only)

IFD Walking (TIFF/EXIF)​

TIFF Header (8 bytes)
│
▼
First IFD Offset ──────► IFD Entry Count (2 bytes)
│
▼
IFD Entries (12 bytes each)
│
├─► Tag ID (2 bytes)
├─► Type (2 bytes)
├─► Count (4 bytes)
└─► Value/Offset (4 bytes)
│
▼
Next IFD Offset (4 bytes)

Coordinate Format​

GPS coordinates use rational numbers (num/denom):

// Internal representation
GPSLatitude: [
{ num: 37, den: 1 }, // degrees
{ num: 45, den: 1 }, // minutes
{ num: 3025, den: 100 } // seconds (30.25")
]

// Output formats
// DMS: "37° 45' 30.25" N"
// Decimal: 37.758403

Performance Characteristics​

Measured on an M2 Max against the reference ExifTool 13.55 binary, 218 real-world JPEGs (~3.1 GB) read by a single process:

Metricexiftool-tsReference exiftool
Batch read, one process2.1 s (~10 ms/file)3.9 s (~18 ms/file)
Cold CLI call, single file~150 ms (node) / ~125 ms (bun)~150 ms
Peak memory, same batch~0.6–0.8 GB (V8 high-water, bounded)~34 MB

The in-process win comes from having no subprocess and no interpreter startup per file; the memory cost comes from the JavaScript runtime's heap management.