Self-hosted service
icloud-photos-downloader/icloud_photos_downloader avatar
icloud-photos-downloader/icloud_photos_downloader

icloudpd: command-line downloads of an entire iCloud photo library

A command-line tool to download photos from iCloud

12,284 stars842 forksPythonMIT

At a glance

What is it?
icloudpd is a Python CLI that mirrors iCloud Photos to a local disk, with copy, sync and move modes plus a watch loop. It is for people with large libraries and a machine that stays on; the README itself says the project is looking for a maintainer.
Who is it for?
Adopt icloudpd if you want a scriptable, self-hosted mirror of a large iCloud library on Linux, macOS, Windows or a NAS, and you accept that the README currently carries a call for a new maintainer. Skip it if you cannot turn off Advanced Data Protection on the Apple ID, or if you want a hosted service that manages the session for you.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 122 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap icloudpd fills: bulk export without the web UI

Apple's web interface is built for browsing, not for taking a copy of a library. icloudpd is a command-line tool whose stated purpose is to download all your iCloud photos, and the README frames it as something that runs on Linux, Windows and macOS, on a laptop, desktop or NAS. That last word matters: the intended deployment is often a machine that is always on, not the phone that took the pictures.

The audience follows from that. Anyone who wants a second copy of a photo library on hardware they control, and who is willing to run a terminal command or a cron job to get it. The examples directory in the repository contains cron_script.sh.example, which tells you the maintainers expect scheduled runs rather than one-off manual exports. The project is written in Python, published under the MIT licence, and distributed both as a standalone executable and through package managers.

Copy, sync and move: three modes with different blast radii

The tool has three modes. Copy is the default and is additive: it downloads photos that are not present locally. Sync adds --auto-delete, which removes local files that were deleted in iCloud, so the local directory becomes a mirror rather than an archive. Move uses --keep-icloud-recent-days and deletes photos in iCloud after downloading them.

Those are very different promises. Copy is the safe default. Sync means a mistake in iCloud propagates to your disk on the next run. Move is the only mode that changes the source of truth, and it is the one to think hardest about, because the README does not describe a rollback path for deletions performed in iCloud. If you want a backup, stay in copy mode and let the remote library stay authoritative.

Around those modes the tool handles the fiddly parts of a real library: Live Photos, where the image and video are stored as separate files; RAW images including RAW+JPEG pairs; and de-duplication of photos that share a filename. For repeated runs there are incremental options, --until-found and --recent, and --watch-with-interval keeps a process alive to poll for changes instead of relying on cron. EXIF timestamps can be written back with --set-exif-datetime. The README points to --help for the rest of the flag set rather than listing everything.

Install and a first real run with icloudpd

The README gives three routes: download the executable for your platform from the GitHub release, install through a package manager (Docker, PyPI, AUR or npm), or build from source. Installation details live in the project documentation under install.html, not in the README itself.

If you go the PyPI route, the package name is icloudpd, matching the project name in pyproject.toml:

bash
pip install icloudpd

Before the first download, check the iCloud prerequisites. The README is explicit that the account must have Access iCloud Data on the Web enabled under Settings > Apple ID > iCloud, and Advanced Data Protection disabled, otherwise Apple's servers return an ACCESS_DENIED error. This is a hard dependency, not a suggestion.

A first run that mirrors the library to a local directory and then keeps watching for new photos every hour looks like this:

bash
icloudpd --directory /data --username [email protected] --watch-with-interval 3600

The README warns that the executable is icloudpd, not icloud. If you are using the Docker image, the entrypoint requires the command name as the first argument, so the same run becomes:

bash
docker run <image> icloudpd --directory /data --username [email protected]

Expect an authentication prompt, including two-factor or two-step validation, on the first run. If you would rather separate authentication from downloading, the README documents an auth-only path that creates and authorizes a session, and notes it can also be used to check whether the session is still valid:

bash
icloudpd --username [email protected] --password my_password --auth-only

After that, files should appear under the directory you passed. Run icloudpd --help to see the full flag list, since the README covers only a subset.

Advanced Data Protection is the blocking constraint

The prerequisite that Advanced Data Protection must be off is the single biggest limitation, and it deserves more attention than the README gives it. Advanced Data Protection is an account-wide security setting. Turning it off to let a third-party tool authenticate against iCloud is a real reduction in the protection of your data, and it affects every device on the account, not just the machine running icloudpd.

The right response is not to argue with the constraint but to plan around it. If you cannot or will not disable Advanced Data Protection, this is the wrong tool, and no flag will change that. The same applies to managed Apple IDs where you do not control the security settings.

There is a second boundary that the README does not address at all: deletion semantics. Move mode deletes photos in iCloud, and the README does not document rollback. Sync mode deletes local files. Neither behaviour is reversible through the tool. Treat both as one-way operations and keep an independent copy of anything you cannot afford to lose.

How icloudpd compares with the Photos app and with Apple's own export

The obvious alternative is the Photos app on macOS, which can download originals to a local library. The difference is the execution model. Photos is interactive and tied to a Mac with enough disk space and a signed-in Apple ID; icloudpd is a headless command you can put in a cron job on a NAS or a Linux server, which is exactly the deployment the README advertises. If you already live in Photos on a Mac and want a browsable library, icloudpd is the wrong shape of tool.

The second alternative is Apple's own data export, which produces an archive rather than a directory tree. That is fine for a one-time snapshot and poor for keeping a folder in step with a library that keeps growing. icloudpd's incremental options and watch loop exist for the second case.

A third comparison worth making is against the many commercial iCloud download utilities. Those usually bundle a GUI and take responsibility for session handling. icloudpd gives you a flag set, a Docker image and a cron example instead. The trade is control for convenience, and the control is real: you decide where the files land and how often the job runs.

Maintenance status, licence and upgrade cost

The repository is not archived, and the most recent push was on 2026-05-30, the same day as the v1.32.3 release. The README opens with a link to issue 1305 titled Looking for MAINTAINER for this project, and it describes the project as developed and maintained by volunteers. That is a fair warning about bus factor: the code works, but the pool of people who will fix it when Apple changes something is small.

The release cadence the README states is a target of one version each Friday, if there is something worth delivering. The gap between v1.32.2 in September 2025 and v1.32.3 in May 2026 shows that the target is aspirational rather than a commitment.

On licensing, the project is MIT. You may use, modify and redistribute it, including commercially, provided the licence and copyright notice are preserved. That is a permissive licence with few obligations. It does not, however, grant anything regarding Apple's services or your account, and it says nothing about whether automated access fits within Apple's terms. That question is outside the licence text and worth resolving yourself before you build a pipeline on this.

Editorial conclusion

Adopt icloudpd if you want a scriptable, self-hosted mirror of a large iCloud library on Linux, macOS, Windows or a NAS, and you accept that the README currently carries a call for a new maintainer. Skip it if you cannot turn off Advanced Data Protection on the Apple ID, or if you want a hosted service that manages the session for you. Before trusting it with a full archive, verify three things on your own account: that the prerequisites are satisfied so the server does not return ACCESS_DENIED, that a small run with --directory and --username lands files where you expect, and that your keyring choice survives a reboot so --auth-only does not have to be repeated.

Frequently asked questions

Is there a way to download all photos from iCloud with icloudpd?

Yes. The README describes icloudpd as a command-line tool to download all your iCloud photos, with copy mode as the default behaviour and incremental options such as --until-found and --recent for repeat runs.

Can icloudpd download iCloud photos directly to an external hard drive?

The tool writes to whatever path you pass to --directory, so a mounted external drive works as a destination. The README does not discuss external drives specifically, and it does not document what happens if the drive disappears mid-run.

How do I download photos from iCloud using icloudpd?

Install it from the release executable or a package manager such as PyPI, Docker, AUR or npm, then run icloudpd with --directory and --username. The first run prompts for authentication, including two-factor validation, and files appear under the directory you specified.

Can icloudpd download more than 1000 photos from iCloud?

The README does not state a photo limit. It describes incremental runs via --until-found and --recent and a continuous watch mode via --watch-with-interval, which are the mechanisms intended for libraries that keep growing.

Official sources

  1. icloud-photos-downloader/icloud_photos_downloader on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/icloud-photos-downloader-icloud-photos-downloader.svg)](https://hysenlabs.com/projects/icloud-photos-downloader-icloud-photos-downloader)