strip-exif-cli
v1.0.0
Published
Remove metadata (EXIF GPS/date/camera, XMP, IPTC, PNG text) from JPEG/PNG images before sharing or uploading. Pure JavaScript, zero dependencies.
Maintainers
Readme
strip-exif-cli
Remove metadata (EXIF GPS/date/camera info, XMP, IPTC, PNG text chunks) from JPEG and PNG images — before you share or upload them.
Pure JavaScript. Zero dependencies. Works offline; your images never leave your machine.
Photos you take with a phone or camera usually embed hidden data: the exact GPS coordinates where the photo was taken, the date and time, and your camera/phone model. When you upload that photo somewhere, you may be leaking your home address or daily routine without realizing it. strip-exif removes that metadata.
New to image metadata and why it's a privacy concern? Read this plain-language guide: What Is Metadata? The Hidden Data About Your Data — Priviy
Install
npm install -g strip-exif-cliOr run without installing:
npx strip-exif-cli photo.jpgUsage
strip-exif <file...> [options]# Clean a photo -> writes photo.clean.jpg next to it
strip-exif photo.jpg
# Clean many files, overwriting them in place
strip-exif *.jpg --in-place
# Write to a specific path
strip-exif photo.jpg -o safe-to-share.jpg
# Just SEE what metadata is in a file (writes nothing)
strip-exif photo.jpg --inspectOptions
| Option | Description |
| --- | --- |
| -o, --out <path> | Write output to <path> (single input only). |
| -s, --suffix <s> | Suffix for output files (default .clean), e.g. photo.clean.jpg. |
| --in-place | Overwrite the input file(s). |
| -i, --inspect | Show the metadata that would be removed; write nothing. |
| -q, --quiet | Only print errors. |
| -h, --help | Show help. |
| -v, --version | Show version. |
Example
$ strip-exif vacation.jpg --inspect
vacation.jpg (jpeg): 2 metadata block(s):
- APP1 (EXIF/XMP) (8.4 KB) EXIF (camera/GPS/timestamp data)
- COM (comment) (46 B) comment: "Shot on iPhone..."
$ strip-exif vacation.jpg
vacation.jpg -> vacation.clean.jpg: removed 2 block(s) [APP1 (EXIF/XMP), COM (comment)], 8.4 KB stripped.What exactly does it remove?
JPEG — removes:
APP1— EXIF (GPS coordinates, capture date/time, camera & lens model, exposure settings) and XMP (Adobe metadata).APP2–APP15— other application metadata segments.APP13— Photoshop / IPTC records (author, copyright, captions, location names).COM— embedded comments.
It keeps APP0 (JFIF) and all image-structure segments (DQT, DHT, SOFn, SOS, the compressed image data) so the output stays a valid, viewable JPEG. The pixels are not re-encoded or degraded — only metadata bytes are dropped.
PNG — removes tEXt, zTXt, iTXt (text/keyword metadata), tIME (last-modified timestamp), and eXIf (embedded EXIF). It keeps IHDR, IDAT, color/structural chunks (PLTE, tRNS, gAMA, sRGB, iCCP, …) and IEND.
Honest limitations
So you know exactly what you get:
- Supports JPEG and PNG only. Other formats (HEIC, WebP, TIFF, video) are rejected with a clear error rather than silently passed through.
- It strips metadata segments, not steganographic data hidden inside the pixels themselves.
- It does not re-compress the image, so it cannot remove an attacker's data deliberately embedded in pixel values — its job is the standard EXIF/XMP/IPTC/text metadata that cameras and editors add.
- The JPEG color profile inside an EXIF block is removed along with EXIF; if you rely on an embedded ICC profile that lives in EXIF, inspect first.
Use as a library
const { strip, inspect } = require('strip-exif-cli');
const fs = require('fs');
const buf = fs.readFileSync('photo.jpg');
// See what's there
console.log(inspect(buf)); // { format: 'jpeg', found: [ ... ] }
// Strip it
const { output, removed, format } = strip(buf);
fs.writeFileSync('photo.clean.jpg', output);
console.log(`Removed ${removed.length} metadata block(s).`);How it works
strip-exif parses the file's container structure directly:
- For JPEG, it walks the marker stream (
0xFFxx), copying image-structure segments verbatim and dropping the metadata application segments. Parsing stops at the start-of-scan marker, after which the compressed image data is copied byte-for-byte. - For PNG, it walks the chunk list (
length | type | data | CRC) and drops the ancillary text/timestamp/EXIF chunks while preserving everything structural.
The operation is lossless for image data and idempotent — running it twice produces a byte-identical result.
Tests
npm testThe test suite builds a JPEG fixture that genuinely embeds an EXIF block with a GPS IFD (latitude/longitude) plus a comment, then asserts that after stripping, the EXIF marker, the GPS IFD tag, and the comment bytes are all gone — while the JFIF header and image scan data remain intact. It does the same for a PNG with text and timestamp chunks.
Learn more about metadata privacy
If you want to understand what metadata is, what your files reveal about you, and how to protect yourself, Priviy publishes a clear guide:
License
MIT © ricco020
