Organize your Google Takeout photo exports by year and album, with full EXIF metadata.
- Download your Google Takeout (select Google Photos only)
- Place all ZIP files in a folder
- Run:
cd /path/to/your/takeout-zips npx google-takeout-photos-organizer - Find your organized photos in
./Google Photos/
Google Photos/
├── 2012/ # Photos organized by year
├── 2013/
├── 2014/
├── ...
├── Vacation 2023/ # Your albums preserved
├── Family/
├── Screenshots/
└── unknown/ # Photos without date metadata
Same photo appears in both its year folder AND album folder (using hard links to save disk space).
- Automatic Extraction — Unpacks all
takeout-*.zipfiles - Smart Organization — Photos sorted by year AND album
- Full EXIF Metadata — Dates, GPS coordinates, descriptions written to files
- Space Efficient — Uses hard links so album copies don't use extra space
- Duplicate Handling — Preserves all variants (
photo.jpg,photo(1).jpg, etc.) - Progress Tracking — Phase-by-phase progress with file counts
- Detailed Logging — Full logs for troubleshooting
| Option | Description | Default |
|---|---|---|
-i, --input <dir> |
Folder containing ZIP files | Current directory |
-o, --output <dir> |
Output folder | ./Google Photos |
-h, --help |
Show help | |
-V, --version |
Show version |
# Process ZIPs in current directory
npx google-takeout-photos-organizer
# Specify input and output directories
npx google-takeout-photos-organizer -i ~/Downloads/takeout -o ~/Pictures/Organized
# Show help
npx google-takeout-photos-organizer --help- Node.js 24 or higher
- Disk space: ~2x your Takeout size (for extraction + organized output)
The tool processes your photos in 6 phases:
| Phase | What Happens |
|---|---|
| 1. Extract | Unpacks all takeout-*.zip files to a staging area |
| 2. Discover | Finds photos/videos and matches them with metadata JSON |
| 3. Analyze | Detects duplicates and calculates date ranges |
| 4. Organize | Copies files to year folders, creates hard links for albums |
| 5. EXIF | Writes metadata directly into photo files |
| 6. Timestamps | Sets file dates to match when photos were taken |
| Tag | Source |
|---|---|
DateTimeOriginal |
When the photo was taken |
CreateDate |
Creation timestamp |
GPSLatitude/Longitude |
Geolocation (if available) |
GPSAltitude |
Altitude (if available) |
ImageDescription |
Photo description from Google Photos |
Title |
Photo title |
Keywords |
Album names |
Photos: JPG, JPEG, PNG, GIF, HEIC, HEIF, WEBP, BMP, TIFF, RAW, CR2, NEF, ARW, DNG
Videos: MP4, MOV, AVI, MKV, WEBM, 3GP, M4V
Make sure you're in the folder containing takeout-*.zip files, or use -i to specify the path:
npx google-takeout-photos-organizer -i /path/to/zipsSome file formats don't support EXIF metadata. The tool continues processing other files.
Large exports can take a while. Check progress in ./logs/processing.log.
LOG_LEVEL=debug npx google-takeout-photos-organizerAfter processing, check:
./logs/processing.log— Full operation log (JSON format)./logs/errors.log— Errors and warnings only
For power users, create a config/default.json file:
{
"input": {
"zipDirectory": ".",
"zipPattern": "takeout-*.zip"
},
"output": {
"stagingDir": ".takeout-staging",
"outputDir": "Google Photos",
"byYearSubdir": "",
"byAlbumSubdir": "",
"unknownYearFolder": "unknown"
},
"processing": {
"concurrency": 5,
"useHardLinks": true,
"fallbackToCopy": true
},
"exif": {
"writeGPS": true,
"writeDescription": true,
"writeKeywords": true,
"writeDateTimeOriginal": true
}
}Google Takeout exports photos in album folders. This tool:
- Copies each photo to a year folder (e.g.,
2023/photo.jpg) - Hard links the same file in the album folder (e.g.,
Vacation/photo.jpg)
Hard links mean the file appears in both places without using extra disk space. Editing one edits both.
The tool determines the year using:
photoTakenTime— When the photo was actually taken (preferred)creationTime— When uploaded to Google Photos- Filename pattern — Dates like
2023-01-15in filename - File modification time — Last resort
unknown/folder — If all methods fail
Expected time for ~20,000 files (56GB):
| Phase | Time |
|---|---|
| Extraction | ~2 min |
| Discovery | <1 sec |
| Analysis | <10 sec |
| Organization | ~1.5 min |
| EXIF Writing | ~2.5 min |
| Timestamps | <5 sec |
| Total | ~6 min |
npm install -g google-takeout-photos-organizer
google-takeout-photos-organizergit clone https://github.com/Flo5k5/google-takeout-photos-organizer.git
cd google-takeout-photos-organizer
npm install
npm run build
npm startnpm run dev # Runs with tsx, no build neededMIT — see LICENSE
Florian NOURRISSE — GitHub
Contributions welcome! Please submit a Pull Request.