This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 57).
Expo MediaLibrary
A library that provides access to the device's media library.
expo-media-library provides access to the user's media library, allowing apps to read existing images and videos, as well as save new ones.
On Android, full access to the media library (the main purpose of this package) is allowed only for apps that require broad access to photos. See details on Google Play's Photo and Video Permissions policy.
Installation
- npx expo install expo-media-libraryIf you are installing this in an existing React Native app, make sure to install expo in your project.
Usage
Add a new asset from the web
import { View, Text } from 'react-native'; import { Image } from 'expo-image'; import { useEffect, useState } from 'react'; import { File, Paths } from 'expo-file-system'; import { Asset, requestPermissionsAsync } from 'expo-media-library'; export default function SaveToMediaLibraryExample() { const [asset, setAsset] = useState<Asset | null>(null); const downloadFile = async () => { const url = 'https://picsum.photos/200/300'; const destinationFile = new File(Paths.cache, 'test_image.jpg'); if (destinationFile.exists) { return destinationFile; } else { return File.downloadFileAsync(url, destinationFile); } }; useEffect(() => { const downloadAndSaveAsset = async () => { const file = await downloadFile(); const { status } = await requestPermissionsAsync(); if (status !== 'granted') { return; } const asset = await Asset.create(file.uri); setAsset(asset); }; downloadAndSaveAsset(); }, []); return ( <View> {asset ? ( <> <Text>{asset.id}</Text> <Image source={{ uri: asset.id }} style={{ width: 200, height: 300 }} /> </> ) : ( <Text>Downloading and creating asset...</Text> )} </View> ); }
Retrieve asset properties
import { View, Text } from 'react-native'; import { useEffect, useState } from 'react'; import { AssetField, MediaType, Query, requestPermissionsAsync } from 'expo-media-library'; export default function RetrievingAssetPropertiesExample() { const [assetInfo, setAssetInfo] = useState<{ id: string; filename: string; mediaType: string; width: number; height: number; creationTime: number | null; modificationTime: number | null; } | null>(null); useEffect(() => { const querySomeAsset = async () => { const { status } = await requestPermissionsAsync(); if (status !== 'granted') { return; } const [asset] = await new Query().limit(1).eq(AssetField.MEDIA_TYPE, MediaType.IMAGE).exe(); if (asset) { const filename = await asset.getFilename(); const mediaType = (await asset.getMediaType()).toString(); const width = await asset.getWidth(); const height = await asset.getHeight(); const creationTime = await asset.getCreationTime(); const modificationTime = await asset.getModificationTime(); setAssetInfo({ id: asset.id, filename, mediaType, width, height, creationTime, modificationTime, }); } else { console.log('No assets found in the media library.'); } }; querySomeAsset(); }, []); return ( <View> {assetInfo ? ( <View> <Text>Asset ID: {assetInfo.id}</Text> <Text>Filename: {assetInfo.filename}</Text> <Text>Media Type: {assetInfo.mediaType}</Text> <Text> Dimensions: {assetInfo.width} x {assetInfo.height} </Text> <Text> Creation Time:{' '} {assetInfo.creationTime ? new Date(assetInfo.creationTime).toLocaleString() : 'Unavailable'} </Text> <Text> Modification Time:{' '} {assetInfo.modificationTime ? new Date(assetInfo.modificationTime).toLocaleString() : 'Unavailable'} </Text> </View> ) : ( <Text>Fetching asset ...</Text> )} </View> ); }
Create a new album
import { View, Text, FlatList, Image, Button } from 'react-native'; import { useState } from 'react'; import { Asset, AssetField, MediaType, Query, requestPermissionsAsync, Album, } from 'expo-media-library'; export default function CreateAlbumExample() { const [assets, setAssets] = useState<Asset[]>([]); const [album, setAlbum] = useState<Album | null>(null); const [albumTitle, setAlbumTitle] = useState<string>(''); const createAlbumWithAsset = async () => { await requestPermissionsAsync(); const [asset] = await new Query().limit(1).eq(AssetField.MEDIA_TYPE, MediaType.IMAGE).exe(); if (!asset) { console.log('No assets found in the media library.'); return; } const newAlbum = await Album.create('MyNewAlbum', [asset]); setAlbum(newAlbum); setAlbumTitle(await newAlbum.getTitle()); const albumAssets = await newAlbum.getAssets(); setAssets(albumAssets); }; return ( <View style={{ flex: 1, padding: 20 }}> <Button title="Create Album and Add Asset" onPress={createAlbumWithAsset} /> {assets.length > 0 ? ( <> <Text style={{ marginTop: 20, fontSize: 18, fontWeight: 'bold' }}> Assets in {albumTitle}: </Text> <FlatList data={assets} keyExtractor={item => item.id} renderItem={({ item }) => ( <View style={{ marginVertical: 10 }}> <Image source={{ uri: item.id }} style={{ width: 100, height: 100, borderRadius: 8 }} /> </View> )} /> </> ) : ( <Text style={{ marginTop: 20 }}>{album ? 'Album is empty.' : 'No album created yet.'}</Text> )} </View> ); }
API
Hooks
| Parameter | Type |
|---|---|
| options(optional) | PermissionHookOptions<{
granularPermissions: GranularPermission[],
writeOnly: boolean
}> |
Check or request permissions to access the media library.
This uses both requestPermissionsAsync and getPermissionsAsync to interact with the permissions.
[PermissionResponse | null, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]Example
const [permissionResponse, requestPermission] = MediaLibrary.usePermissions({ writeOnly: true, granularPermissions: ['photo'], });
Classes
Represents a media album (collection of assets) on the device.
An Album groups together media assets (images, videos, or audio files).
To create a new album, use Album.create().
To fetch an existing album, use Album.get().
Album Properties
stringUnique identifier of the album.
Can be used to re-instantiate an Album later.
Album Methods
Adds one or more assets to the album.
Promise<void>A promise that resolves once the assets have been added.
Example
const asset = await Asset.create("file:///path/to/photo.png"); await album.add(asset);
Example
await album.add([asset1, asset2]);
| Parameter | Type | Description |
|---|---|---|
| name | string | Name of the new album. |
| assetsRefs | string[] | Asset[] | List of |
| moveAssets(optional) | boolean | On Android, whether to move assets into the album. Defaults to |
A static function. Creates a new album with a given name and assets.
On Android, if assets are provided and moveAssets is true, the assets will be moved into the new album. If false or not supported, the assets will be copied.
A promise resolving to the created Album.
Example
const album = await Album.create("My Album", [asset]); console.log(await album.getTitle()); // "My Album"
Permanently deletes the album from the device. On Android, it deletes the album and all its assets. On iOS, it deletes the album but keeps the assets in the main library.
Promise<void>A promise that resolves once the deletion has completed.
Example
await album.delete();
| Parameter | Type | Description |
|---|---|---|
| albums | Album[] | An array of |
| deleteAssets(optional) | boolean | On iOS, whether to delete the assets in the albums as well. Defaults to |
A static function. Deletes multiple albums at once.
On Android, assets are always deleted along with the album regardless of deleteAssets.
Promise<void>A promise that resolves once the albums have been deleted.
Example
const album = await Album.create("My Album", [asset]); await Album.delete([album]);
| Parameter | Type | Description |
|---|---|---|
| title | string | The title of the album to retrieve. |
Gets the display title (name) of the album. Note that album titles are not guaranteed to be unique.
Promise<string>A promise resolving to the album's title string.
Example
const title = await album.getTitle(); console.log(title); // "Camera"
Removes assets from the album without deleting them from the library. This is supported only on iOS.
On Android, an asset can belong to only one album. To remove it from an album, delete it or add it to another album.
Promise<void>A promise that resolves once the assets have been removed.
Example
const assets = await album.getAssets(); await album.removeAssets(assets.slice(0, 2));
Represents a media asset in the device media library.
Asset Properties
stringAsset identifier.
Can be used to re-instantiate an Asset later.
Asset Methods
| Parameter | Type | Description |
|---|---|---|
| filePath | string | Local file URI of the asset to create. |
| album(optional) | Album | Optional album to add the created asset to. |
Deletes the asset from the media library.
Promise<void>A promise resolving once the deletion has completed.
| Parameter | Type | Description |
|---|---|---|
| assets | Asset[] | Assets to delete. |
Deletes multiple assets from the media library.
Promise<void>A promise resolving once deletion has completed.
Gets the asset creation time.
Promise<number | null>A promise resolving to a timestamp in seconds, or null when the value is unavailable.
Gets the asset duration.
Promise<number | null>A promise resolving to the duration in seconds, or null when the value is unavailable.
Gets whether the asset is marked as a favorite.
On iOS, this checks if the asset is part of the system "Favorites" smart album.
On Android, this reads the IS_FAVORITE column from MediaStore. It requires Android 10+
and always returns false on older versions.
Promise<boolean>A promise resolving to true if the asset is a favorite, otherwise false.
Gets whether the asset is stored in iCloud and not available locally. This does not trigger a download of the asset.
Promise<boolean>A promise resolving to true if the asset is stored in iCloud and unavailable locally, otherwise false.
Gets the URI of the paired video for a Live Photo asset. The video is extracted to a temporary file.
Promise<string | null>A promise resolving to the paired video URI, or null if the asset is not a Live Photo or no paired video is available.
Gets the media subtypes of the asset, describing specific variations such as Live Photo, panorama, HDR, etc.
Promise<MediaSubtype[]>A promise resolving to an array of MediaSubtype values.
Gets the asset modification time.
Promise<number | null>A promise resolving to a timestamp in seconds, or null when the value is unavailable.
Gets the EXIF display orientation of the asset.
Only applicable for assets with media type MediaType.IMAGE.
Promise<number | null>A promise resolving to the EXIF orientation value, or null when unavailable.
Gets the asset dimensions.
Promise<Shape | null>A promise resolving to the asset shape, or null when the value is unavailable.
| Parameter | Type | Description |
|---|---|---|
| isFavorite | boolean | Whether the asset should be marked as favorite. |
Marks or unmarks the asset as a favorite.
On iOS, this adds or removes the asset from the system "Favorites" smart album.
On Android, this updates the IS_FAVORITE column in MediaStore. It requires Android 10+
and is a no-op on older versions.
Promise<void>A promise that resolves once the favorite state has been updated.
On Android, some third-party gallery apps maintain their own favorites list and may not reflect changes made through this method.
Represents a query to fetch data from the media library.
A query implements a builder pattern, allowing you to chain multiple filtering and sorting methods
to construct complex queries.
Query Methods
| Parameter | Type | Description |
|---|---|---|
| album | Album | The album to filter assets by. |
Filters assets to only those contained in the specified album.
QueryThe updated query object for chaining.
| Parameter | Type | Description |
|---|---|---|
| field | T | an |
| value | AssetFieldValueMap[T] | The value that the field should equal. Each field has a specific unique type. |
Filters assets where the specified field is equal to the given value.
QueryThe updated query object for chaining.
Executes the query and retrieves the matching assets.
A promise that resolves to an array of Asset objects that match the query criteria.
Example
const assets = await new Query() .eq(AssetField.MEDIA_TYPE, MediaType.IMAGE) .lte(AssetField.HEIGHT, 1080) .orderBy(AssetField.CREATION_TIME) .limit(20) .exe();
Executes the query and retrieves lightweight metadata for the matching assets.
Returns fields that can be read cheaply from the media store, without resolving file paths or decoding files.
Promise<AssetMetadata[]>A promise that resolves to an array of AssetMetadata objects that match the query criteria.
Example
const assets = await new Query() .eq(AssetField.MEDIA_TYPE, MediaType.IMAGE) .lte(AssetField.HEIGHT, 1080) .orderBy(AssetField.CREATION_TIME) .limit(20) .exeForMetadata();
| Parameter | Type | Description |
|---|---|---|
| field | AssetField | an |
| value | number | The value that the field should be greater than. |
Filters assets where the specified field is greater than the given value.
QueryThe updated query object for chaining.
| Parameter | Type | Description |
|---|---|---|
| field | AssetField | an |
| value | number | The value that the field should be greater than or equal to. |
Filters assets where the specified field is greater than or equal to the given value.
QueryThe updated query object for chaining.
| Parameter | Type | Description |
|---|---|---|
| limit | number | The maximum number of results to return. |
Limits the number of results returned by the query.
QueryThe updated query object for chaining.
| Parameter | Type | Description |
|---|---|---|
| field | AssetField | an |
| value | number | The value that the field should be less than. |
Filters assets where the specified field is less than the given value.
QueryThe updated query object for chaining.
| Parameter | Type | Description |
|---|---|---|
| field | AssetField | an |
| value | number | The value that the field should be less than or equal to. |
Filters assets where the specified field is less than or equal to the given value.
QueryThe updated query object for chaining.
| Parameter | Type | Description |
|---|---|---|
| offset | number | The number of results to skip. |
| Parameter | Type | Description |
|---|---|---|
| sortDescriptors | AssetField | SortDescriptor | An instance of SortDescriptor or an AssetField. If an AssetField is provided, the sorting will be done in ascending order by default. |
Orders the results by the specified sort descriptor or asset field.
QueryThe updated query object for chaining.
| Parameter | Type | Description |
|---|---|---|
| field | T | an |
| value | undefined | An array of values that the field should match. Each field has a specific unique type. |
Filters assets where the specified field's value is in the given array of values.
QueryThe updated query object for chaining.
Methods
Deprecated: Use
album.add()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| assets | AssetRef | AssetRef[] |
| album | AlbumRef |
| copy(optional) | boolean |
Promise<boolean>Deprecated: Import this method from
expo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| album | AlbumRef |
Promise<boolean>Deprecated: Use
Album.create()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| albumName | string |
| asset(optional) | AssetRef |
| copyAsset(optional) | boolean |
| initialAssetLocalUri(optional) | string |
Deprecated: Use
Asset.create()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| localUri | string |
| album(optional) | AlbumRef |
Deprecated: Use
album.delete()orAlbum.delete()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| albums | AlbumRef | AlbumRef[] |
| assetRemove(optional) | boolean |
Promise<boolean>Deprecated: Use
asset.delete()orAsset.delete()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| assets | AssetRef | AssetRef[] |
Promise<boolean>Deprecated: Use
Album.get(title)or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| title | string |
Deprecated: Use
Album.getAll()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| options(optional) | AlbumsOptions |
Deprecated: Import this method from
expo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| asset | AssetRef |
Promise<string>Deprecated: Use
asset.getInfo()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| asset | AssetRef |
| options(optional) | MediaLibraryAssetInfoQueryOptions |
Deprecated: Use the
Queryclass or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| assetsOptions(optional) | AssetsOptions |
Deprecated: Import this method from
expo-media-library/legacy. This method will throw in runtime.
| Parameter | Type | Description |
|---|---|---|
| writeOnly(optional) | boolean | Whether to check write-only access without read permissions. Defaults to Default: false |
| granularPermissions(optional) | GranularPermission[] | A list of |
Checks user's permissions for accessing media library.
Promise<PermissionResponse>A promise that fulfils with PermissionResponse object.
Deprecated: Import this method from
expo-media-library/legacy. This method will throw in runtime.
Promise<boolean>Deprecated: Import this method from
expo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| album | AlbumRef |
Promise<void>| Parameter | Type | Description |
|---|---|---|
| mediaTypes(optional) | MediaTypeFilter[] | Limits the type(s) of media that the user will be granting access to. By default, a list that shows both photos and videos is presented. |
Allows the user to update the assets that your app has access to.
The system modal is only displayed if the user originally allowed only limited access to their
media library, otherwise this method is a no-op.
Promise<void>A promise that either rejects if the method is unavailable, or resolves to void.
Note: This method doesn't inform you if the user changes which assets your app has access to. That information is only exposed by iOS, and to obtain it, you need to subscribe for updates to the user's media library using
addListener(). IfhasIncrementalChangesisfalse, the user changed their permissions.
Deprecated: Use
presentPermissionsPicker()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| mediaTypes(optional) | MediaTypeFilter[] |
Promise<void>Deprecated: Use
album.removeAssets()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| assets | AssetRef | AssetRef[] |
| album | AlbumRef |
Promise<boolean>Deprecated: Use
subscription.remove()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| subscription | EventSubscription |
void| Parameter | Type | Description |
|---|---|---|
| writeOnly(optional) | boolean | Whether to request write-only access without read permissions. Defaults to Default: false |
| granularPermissions(optional) | GranularPermission[] | A list of
|
Asks the user to grant permissions for accessing media in user's media library.
Promise<PermissionResponse>A promise that fulfils with PermissionResponse object.
Deprecated: Use
Asset.create()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| localUri | string |
Promise<void>Deprecated: Use
asset.setFavorite()or import this method fromexpo-media-library/legacy. This method will throw in runtime.
| Parameter | Type |
|---|---|
| asset | AssetRef |
| isFavorite | boolean |
Promise<boolean>Event Subscriptions
| Parameter | Type | Description |
|---|---|---|
| listener | (event: MediaLibraryAssetsChangeEvent) => void | A callback that is fired when any assets have been inserted or deleted from the
library. On Android it's invoked with an empty object. On iOS it's invoked with
|
Subscribes for updates in user's media library.
EventSubscriptionAn EventSubscription object that you can call remove() on when
you would like to unsubscribe the listener.
Interfaces
A subscription object that allows to conveniently remove an event listener from the emitter.
Types
| Property | Type | Description |
|---|---|---|
| creationTime | number | - |
| duration | number | - |
| height | number | - |
| isFavorite | boolean | - |
| mediaType | MediaType | - |
| modificationTime | number | - |
| width | number | - |
| Property | Type | Description |
|---|---|---|
| creationTime | number | null | - |
| duration | number | null | - |
| filename | string | - |
| height | number | - |
| id | string | - |
| isFavorite(optional) | boolean | - |
| mediaType | MediaType | - |
| modificationTime | number | null | - |
| uri | string | - |
| width | number | - |
An object obtained by permissions get and request functions.
| Property | Type | Description |
|---|---|---|
| canAskAgain | boolean | Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission. |
| expires | PermissionExpiration | Determines time when the permission expires. |
| granted | boolean | A convenience boolean that indicates if the permission is granted. |
| status | PermissionStatus | Determines the status of the permission. |
Literal Type: string
Acceptable values are: 'audio' | 'photo' | 'video'
An event emitted when assets in the media library change.
| Property | Type | Description |
|---|---|---|
| deletedAssets(optional) | string[] | Only for: iOS Array of asset IDs ( |
| hasIncrementalChanges | boolean | Whether the media library's changes can be described as incremental changes.
|
| insertedAssets(optional) | string[] | Only for: iOS Array of asset IDs ( |
| updatedAssets(optional) | string[] | Only for: iOS Array of asset IDs ( |
Literal Type: union
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never' | number
Literal Type: union
Acceptable values are: PermissionHookBehavior | Options
Type: EXPermissionResponse extended by:
| Property | Type | Description |
|---|---|---|
| accessPrivileges(optional) | 'all' | 'limited' | 'none' | Indicates if your app has access to the whole or only part of the photo library. Possible values are:
|
| Property | Type | Description |
|---|---|---|
| ascending(optional) | boolean | - |
| key | AssetField | - |
Enums
Describes specific variations of asset media. Maps to PHAssetMediaSubtype.