photo_manager: a Flutter assets API with no user interface attached
A Flutter plugin that provides images, videos, and audio abstraction management APIs without interface integration, available on Android, iOS, macOS and OpenHarmony.
At a glance
- What is it?
- photo_manager gives a Flutter app structured access to the image, video and audio on the device, on Android, iOS, macOS and OpenHarmony, and deliberately ships no picker UI of its own. The library is a set of entities and filters, plus the native configuration each platform needs, which makes it the plumbing under a gallery picker rather than a gallery picker itself.
- Who is it for?
- photo_manager fits a Flutter team that needs to build its own gallery, an upload flow, or an avatar picker on top of the device media library, and that has to support more than one platform with the same Dart code. It does not fit a project that just wants a stock gallery screen, since the library ships no interface and you write the whole picker yourself.
- Can I use it commercially?
- Yes. Apache-2.0 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 received new commits within the last day.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Plumbing rather than a picker
photo_manager is a Flutter plugin that provides assets abstraction management APIs without interface integration. You can get assets, meaning images, video and audio, on Android, iOS, macOS, and OpenHarmony.
That phrase, without interface integration, is the whole positioning, and it is the difference between this library and the picker plugins that look similar in search results. There is no grid, no selection sheet, and no permission dialog designed for you. What you get is a structured view of the media library, expressed as entities you can query, and you build the interface on top.
That makes it the more useful of the two kinds, if you are building something more than a picker. A photo gallery, a chat attachment browser, a media uploader, an avatar chooser with your own design, an app that needs to know whether a video is a Live Photo, all of them need the same underlying access, and each of them needs a different interface.
The proof that the model works is in the list of projects using the plugin, which names wechat_assets_picker and wechat_camera_picker, both published packages with their own repositories. Those are the picker layers, built by other people on top of the access layer, and the fact that they exist as separate projects rather than as features of this one is the clearest statement of the design.
The package is published on pub.dev as photo_manager, written in Dart, licensed under Apache 2.0, and it is not archived, with the last push on 2026-10-19. The release tags are v3.12.0 from 2026-08-09, v3.11.0 from 2026-07-25, and v3.10.0 from 2026-07-09, so it has been shipping a minor version roughly every two weeks.
The repository also holds an example application, an OpenHarmony example, a flow_chart directory, a log directory, a scripts directory, and an analysis options file, and the README is published in both English and Chinese.
Permissions, and the limited access every platform now offers
The usage section starts with requesting permission, and under it there is a subsection called limited entities access, with separate entries for iOS and Android.
That is the part of the documentation that most deserves attention, because the platforms have moved to a model where the user grants access to a selected set of photos rather than to the whole library, and a media library API has to cope with that. The library exposes it rather than hiding it, and the section titles in the table of contents show that the limited access path is documented per platform.
The configuration steps come before usage, and they are the second thing to read, because they are where a first integration usually stops. There is a prepare for use section with three parts: adding the plugin reference to pubspec.yaml, importing it in your projects, and configuring the native platforms.
The native platform configuration has its own subsections. On Android there is the Kotlin, Gradle, and AGP preparation, a note for Android 10, which is API level 29, and a note about Glide. On iOS there is an iOS config preparation section.
The Glide reference is worth pausing on, because it is a dependency rather than a setting. Glide is the image loading library Android applications use, and when a media library plugin hands you file paths or content URIs, the way the image loader is configured determines whether those paths resolve. A section titled Glide issues in the native extra configs later in the document, and another called Glide issues under the Android configuration, tells you that this is a recurring friction point rather than a one-off.
The Android version notes appear in the native extra configs as well, with separate entries for Android 14 at API level 34 and Android 13 at API level 33. Each platform release that changes media permissions tends to need its own configuration, and a library that documents them per version is saving you the archaeology.
Two entity types, and a documented way to fetch each
The core model has two entity types, and the table of contents shows a lot of ways to get at each of them.
AssetPathEntity is an album or folder. There is a getAssetPathList method, its parameters are documented in their own section, and there is a PMPathFilterOption type that was introduced in version 2.7.0 for filtering the paths.
AssetEntity is an individual item, and there are five documented ways to obtain one. You can get assets from an AssetPathEntity, which is the ordinary case of walking an album. You can get them from PhotoManager directly, which the documentation notes has been possible since version 2.6. You can get one by its ID. You can get one from raw data, which is the path for a file that is not yet in the library. And you can get one from iCloud, which is the interesting one, because it is the entry point for assets that live only in Apple's cloud storage.
There is also a cancel loading option, available since version 3.8.0, which is the sort of API that only shows up in a library that has been used in production a lot. Loading a large library is slow, and without a way to cancel, a user who navigates away leaves a request running.
Two capability subsections are worth naming individually. Display assets is about showing the item in the interface, and get asset files is about producing the file itself, which on a modern Android is a content URI rather than a path, and on iOS is a file that may still need to be fetched from iCloud.
Live Photos have their own treatment, because a Live Photo is two things at once. There is a section on obtaining Live Photos, one on filtering to only the Live Photos, and one on obtaining the video from a Live Photo, which is the part an app needs when it wants to share or upload the motion part.
The limitations section is the most useful part of the README
The documentation has a section called limitations, with three named entries, and reading them before you design the feature saves a redesign later.
The first is the Android 10 media location permission. Android 10 introduced a scoped model for media location, so an app that wants to know where a photo was taken needs a separate permission, and the plugin documents it rather than pretending the location is there.
The second is usage of the original data. There is a distinction between the asset as the system presents it, with the edits the user made in the gallery application, and the original file, and an app that wants the untouched original has to ask for it explicitly, and on some devices that data may not be available.
The third is the long retrieving duration with a file on iOS. That is the iCloud case again, and the documentation is straightforward about the consequence: a file that lives in the cloud has to be downloaded before you can use it, and that takes time.
There is also a section on including hidden assets, marked as iOS only, with two ways of doing it, using FilterOptionGroup and using CustomFilter. Hidden assets are the ones the user has marked as hidden in the Photos application, and an app that offers to show them is making a promise about access that has to be honoured on the platform side.
The entity change notification is a separate feature, and it is the one that keeps a gallery correct. Without it, an app that is open while the user takes a photo has a stale list, and the only way to be correct is to reload everything, which is why the notification exists as a first class feature rather than as something you poll for.
Filtering, caching, and the shape of the query layer
The filtering and caching sections together are what turn a list of assets into something you can put behind a screen.
There are two ways to filter. FilterOptionGroup is the structured one, a group of typed options, and it is the API to use for the common case of choosing a type, a time range, and a size. CustomFilter is the general one, and there is an advanced CustomFilter subsection for the cases the structured one does not cover, plus a classes explanations section that documents the types involved.
The custom filter is where the interesting power is, because the underlying query languages on these platforms are expressive. A filter that combines a time window, a media type, and a location predicate is one call on the native side rather than a full library load followed by Dart side filtering, and for a large library that difference is the difference between a screen that opens and one that does not.
The cache mechanism is documented per platform, with a cache on Android section, a cache on iOS section, and a section on clearing the caches. Per platform matters here, because the two systems have different models of what a file is and when it is resolved, and a cache that does not understand the difference produces a file that looks right until you try to use it.
And there is a section on clearing the caches, which is a thing you only find documented in libraries that have been burned. A cache that cannot be invalidated is a cache that will eventually serve a file that has been deleted from the device, and the fix is not obvious from the API.
The native configuration, and the experimental edge
The last part of the documentation is the native extra configs, and it is where the platform specifics live.
On Android there is the Glide issues entry, plus the Android 14 at API 34 and Android 13 at API 33 configuration entries. Each of those is a platform release whose changes are addressed in the plugin's own configuration, and the pattern of one entry per Android version is the clearest evidence that the library tracks the platform actively rather than shipping a generic implementation.
On iOS there is a section on the localized system albums name, which is a small and telling entry. The system albums in Photos are named in the user's language, so a path filter that matches on a hardcoded album name breaks the moment the user switches their device language, and the library documents how to handle that.
The experimental features section lists three things: preload thumbnails, delete entities, and copy an entity. The first is a performance feature for a gallery that shows many items at once, the second is destructive, and the third is a file operation with permissions implications. They are marked experimental, which is the right label for all three.
The platform matrix is in the description rather than in a table: Android, iOS, macOS, and OpenHarmony. The repository layout matches it, with android, darwin, ios, macos, and ohos directories, and the OpenHarmony example application as a separate directory, which is a hint that OpenHarmony is supported at a different level of maturity than the three established platforms.
For anyone upgrading across major versions, the README points to a separate migration guide document with detailed information, which is the document to read before you move from 3.x to 4.x, since the API surface is large enough that the differences will not be obvious from the changelog alone.
Editorial conclusion
photo_manager fits a Flutter team that needs to build its own gallery, an upload flow, or an avatar picker on top of the device media library, and that has to support more than one platform with the same Dart code. It does not fit a project that just wants a stock gallery screen, since the library ships no interface and you write the whole picker yourself. Verify first that the minimum platform versions in your project match what the native configuration sections require, in particular the Android 13 and 14 notes and the Android 10 media location permission, that you have a plan for the limited photo access that iOS and Android now grant, and that you read the migration guide before jumping a major version, because the package documents a separate guide for each major upgrade.
Frequently asked questions
What does the photo_manager Flutter plugin do?
It provides assets abstraction management APIs without interface integration, so you can get images, video, and audio on Android, iOS, macOS, and OpenHarmony. It is the access layer under a gallery or picker, not a gallery UI, and you build the interface yourself.
Which platforms does photo_manager support?
Android, iOS, macOS, and OpenHarmony. The repository has android, darwin, ios, macos, and ohos directories, and there is a separate OpenHarmony example application alongside the main example.
How do I get albums and assets with photo_manager?
getAssetPathList returns albums as AssetPathEntity objects, with PMPathFilterOption for filtering them since version 2.7.0. Assets are AssetEntity objects, and the documentation describes five ways to obtain one, from an album, from PhotoManager directly since 2.6, from an ID, from raw data, and from iCloud.
What limitations does photo_manager document?
Three, under a limitations section: the Android 10 media location permission needed to know where a photo was taken, the use of the original data rather than the edited version, and the long retrieving duration with a file on iOS when the asset still lives in iCloud.
Does photo_manager work without building a user interface?
Yes, and that is the point of the design. The library is documented as providing assets abstraction management APIs without interface integration, and other projects such as wechat_assets_picker and wechat_camera_picker build their own pickers on top of it.
Official sources
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.
[](https://hysenlabs.com/projects/fluttercandies-flutter-photo-manager)Was this useful?