GO

Google Photos Takeout Helper

Organizes Google Photos Takeout exports into a clean library

Photo Management ★ 5.9k stars Medium setup Apache-2.0

Google Photos Takeout Helper is a command-line tool that processes a Google Photos Takeout archive and reconstructs a properly organized, metadata-correct photo library. It is widely used when migrating from Google Photos to self-hosted services like Immich.

Key features

  • Processes Google Takeout archives
  • Restores correct EXIF dates
  • Organizes into albums
  • Migration aid for self-hosting

Pros & cons

Strengths

  • Essential for migration
  • Actively maintained

Trade-offs

  • One-time use tool
  • Command-line oriented

Google Photos Takeout Helper replaces

Last reviewed Sep 13, 2026 · 881 words

A Google Takeout export of your photo library arrives as a pile of zip files in which roughly a third of the images carry no usable date, the albums are folders full of duplicate copies, and every "date taken" you care about is sitting in a .json sidecar next to the file rather than inside it. Google Photos Takeout Helper (GPTH) is a command-line tool that reads those sidecars, writes the timestamps back into EXIF and file modification times, collapses the duplicates, and hands you a folder tree any self-hosted photo server can ingest. You run it once, on the way out of Google, and then you never touch it again.

Why Takeout needs fixing at all

Google stores the metadata it knows about a photo in its own database, not in the file. Photos uploaded from the web, from WhatsApp, from a screenshot folder or from an old phone that stripped EXIF have no DateTimeOriginal inside the JPEG. Takeout writes that knowledge to a sidecar (IMG_1234.jpg.json with a photoTakenTime field) and leaves the image untouched. Import that folder straight into Immich or PhotoPrism and those photos land on the day you imported them, at the very top of your timeline, several thousand of them. Albums are worse: Takeout exports each album as a folder containing a full copy of every photo in it, so a 200 GB library with heavy album use can arrive as 300 GB of files.

GPTH exists because fixing this by hand is not realistic past a few hundred photos. It matches each image to its sidecar (including the truncated and oddly-suffixed names Takeout produces for long filenames and -edited variants), writes the date into EXIF where the format supports it and into the file's modification time everywhere, and de-duplicates by content hash so each photo exists once.

The run itself takes 10 minutes of typing and hours of waiting

Download every zip Takeout produced (choose the 50 GB part size to keep the count down) and extract all of them into one folder, so that the Takeout/Google Photos/ trees merge. Then grab the release binary for your platform from the GitHub releases page and run it:

./gpth --input ~/takeout/Takeout/Google\ Photos --output ~/photos-clean --albums shortcut

Run with no arguments and it walks you through the same choices interactively. The flags that actually change the outcome are --albums (how album membership is preserved), --divide-to-dates (year/month folder tree or one flat directory), and --skip-extras (drop the -edited copies Google made when you applied a filter). Budget 256 MB of RAM and, more importantly, free disk equal to your library size on the output side. On a 150 GB export I would expect a couple of hours on a spinning disk, less on SSD; the bottleneck is I/O, not the Dart runtime.

Album mode is the decision that bites later

shortcut creates symlinks from album folders to the single real file. It is the space-efficient choice and the wrong one if the output drive is exFAT, NTFS mounted on Linux, or a Windows machine without developer mode, because the links silently fail. duplicate-copy makes real copies and doubles your storage again. json writes an albums-info.json and leaves the photos in one folder, which is what I use, because the file is easy to script against and the photo server, not the filesystem, should own albums. nothing throws album information away, which is acceptable only if you never used albums.

Pick before you run. Re-running with a different mode means re-extracting, because GPTH moves files out of the input folder by default.

Immich users: consider immich-go instead

GPTH was the only option for years; now it is not. immich-go, a separate Go tool, reads Takeout zips directly without extraction, applies the sidecar dates during upload, and recreates albums inside Immich through the API. For the specific path of Google Photos to Immich it is faster, uses less disk and gets albums right without symlink games. My migration walkthrough covers that route end to end.

GPTH still wins when the destination is a filesystem: PhotoPrism, a Synology, a plain Syncthing folder, or a cold archive you want readable in 20 years. It produces correct files rather than a correct database, and correct files are what you want if you ever leave the next server too. The broader case for getting out at all is in the Google Photos alternatives guide.

What I'd do

Export at 50 GB part size, extract everything into one directory on an SSD, and run GPTH with --albums json, no date folders, --skip-extras on. Spot-check 20 photos from a known trip against their dates before importing anything. If the destination is Immich, skip GPTH and use immich-go against the zips. If it is anything that reads folders, GPTH is the correct tool and the whole exercise costs one evening. Keep the raw Takeout zips on an external drive for a year afterwards; you will find one photo that came through wrong, and the sidecar will still be there to fix it.

Compare Google Photos Takeout Helper

21 head-to-head comparisons.

Similar photo management apps