Reference version

This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 54).

Expo MediaLibrary (next) iconExpo MediaLibrary (next)

GitHub

Changelog

npm

A library that provides access to the device's media library.

Android
iOS
tvOS

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

Terminal
npx expo install expo-media-library

If 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
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/next'; 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
Retrieve asset properties
import { View, Text } from 'react-native'; import { useEffect, useState } from 'react'; import { AssetField, MediaType, Query, requestPermissionsAsync } from 'expo-media-library/next'; 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
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/next'; 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

Classes

Album

Android
iOS
tvOS

Type: Class extends Album

Album Properties

id

Android
iOS
tvOS
Type: string

Unique identifier of the album. Can be used to re-instantiate an Album later.

Album Methods

add(asset)

Android
iOS
tvOS
ParameterTypeDescription
assetAsset

The Asset to add.


Adds an asset to the album.

Returns:
Promise<void>

A promise that resolves once the asset has been added.

Example

const asset = await Asset.create("file:///path/to/photo.png"); await album.add(asset);

create(name, assetsRefs, moveAssets)

Android
iOS
tvOS
ParameterTypeDescription
namestring

Name of the new album.

assetsRefsstring[] | Asset[]

List of Asset objects or file paths (file:///...) to include.

moveAssets(optional)boolean

On Android, whether to move assets into the album.

Default:true

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.

Returns:
Promise<Album>

A promise resolving to the created Album.

Example

const album = await Album.create("My Album", [asset]); console.log(await album.getTitle()); // "My Album"

delete()

Android
iOS
tvOS

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.

Returns:
Promise<void>

A promise that resolves once the deletion has completed.

Example

await album.delete();

delete(albums, deleteAssets)

Android
iOS
tvOS
ParameterTypeDescription
albumsAlbum[]

An array of Album instances to delete.

deleteAssets(optional)boolean

Whether to delete the assets in the albums as well.

Default:false

A static function. Deletes multiple albums at once.

Returns:
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]);

get(title)

Android
iOS
tvOS
ParameterTypeDescription
titlestring

The title of the album to retrieve.


A static function. Retrieves an album by its title.

Returns:
Promise<null | Album>

A promise resolving to the Album if found, or null if not found.

Example

const album = await Album.get("Camera"); if (album) { console.log(await album.getTitle()); // "Camera" }

getAssets()

Android
iOS
tvOS

Retrieves all assets contained in the album.

Returns:
Promise<Asset[]>

A promise resolving to an array of Asset objects.

Example

const assets = await album.getAssets(); console.log(assets.length);

getTitle()

Android
iOS
tvOS

Gets the display title (name) of the album. Note that album titles are not guaranteed to be unique.

Returns:
Promise<string>

A promise resolving to the album’s title string.

Example

const title = await album.getTitle(); console.log(title); // "Camera"

Asset

Android
iOS
tvOS

Type: Class extends Asset

Asset Properties

id

Android
iOS
tvOS
Type: string

ID of the asset. Can be used to re-instantiate an Asset later. For android it is a contentUri and PHAsset localIdentifier for iOS.

Asset Methods

create(filePath, album)

Android
iOS
tvOS
ParameterTypeDescription
filePathstring

Local filesystem path (for example, file:///...) of the file to import.

album(optional)Album

Optional Album instance to place the asset in.


A static function. Creates a new asset from a given file path. Optionally associates the asset with an album. On Android, if not specified, the asset will be placed in the default "Pictures" directory.

Returns:
Promise<Asset>

A promise resolving to the created Asset.

Example

const asset = await Asset.create("file:///storage/emulated/0/DCIM/Camera/IMG_20230915_123456.jpg"); console.log(await asset.getFilename()); // "IMG_20230915_123456.jpg"

delete()

Android
iOS
tvOS

Deletes the asset from the device’s media store.

Returns:
Promise<void>

A promise that resolves once the deletion has completed.

Example

await asset.delete();

delete(assets)

Android
iOS
tvOS
ParameterType
assetsAsset[]

Returns:
Promise<void>

getCreationTime()

Android
iOS
tvOS

Gets the creation time of the asset.

Returns:
Promise<null | number>

A promise resolving to the UNIX timestamp in milliseconds, or null if unavailable.

getDuration()

Android
iOS
tvOS

Gets the duration of the asset. Applies only to media types like video or audio.

Returns:
Promise<null | number>

A promise resolving to the duration in milliseconds, or null if not applicable.

getFilename()

Android
iOS
tvOS

Gets the filename of the asset, including its extension.

Returns:
Promise<string>

A promise resolving to the filename string.

getHeight()

Android
iOS
tvOS

Gets the height of the asset in pixels. Only applicable for image and video assets.

Returns:
Promise<number>

A promise resolving to the height in pixels.

getMediaType()

Android
iOS
tvOS

Gets the media type of the asset (image, video, audio or unknown).

A promise resolving to a MediaType enum value.

getModificationTime()

Android
iOS
tvOS

Gets the last modification time of the asset.

Returns:
Promise<null | number>

A promise resolving to the UNIX timestamp in milliseconds, or null if unavailable.

getUri()

Android
iOS
tvOS

Gets the URI pointing to the asset’s location in the system. Example, for Android: file:///storage/emulated/0/DCIM/Camera/IMG_20230915_123456.jpg.

Returns:
Promise<string>

A promise resolving to the string URI.

getWidth()

Android
iOS
tvOS

Gets the width of the asset in pixels. Only applicable for image and video assets.

Returns:
Promise<number>

A promise resolving to the width in pixels.

Query

Android
iOS
tvOS

Type: Class extends Query

Query Methods

album(album)

Android
iOS
tvOS
ParameterTypeDescription
albumAlbum

The album to filter assets by.


Filters assets to only those contained in the specified album.

Returns:
Query

The updated query object for chaining.

eq(field, value)

Android
iOS
tvOS
ParameterTypeDescription
fieldT

an AssetField to filter by.

valueAssetFieldValueMap[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.

Returns:
Query

The updated query object for chaining.

exe()

Android
iOS
tvOS

Executes the query and retrieves the matching assets.

Returns:
Promise<Asset[]>

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();

gt(field, value)

Android
iOS
tvOS
ParameterTypeDescription
fieldAssetField

an AssetField to filter by.

valuenumber

The value that the field should be greater than.


Filters assets where the specified field is greater than the given value.

Returns:
Query

The updated query object for chaining.

gte(field, value)

Android
iOS
tvOS
ParameterTypeDescription
fieldAssetField

an AssetField to filter by.

valuenumber

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.

Returns:
Query

limit(limit)

Android
iOS
tvOS
ParameterTypeDescription
limitnumber

The maximum number of results to return.


Limits the number of results returned by the query.

Returns:
Query

The updated query object for chaining.

lt(field, value)

Android
iOS
tvOS
ParameterTypeDescription
fieldAssetField

an AssetField to filter by.

valuenumber

The value that the field should be less than.


Filters assets where the specified field is less than the given value.

Returns:
Query

The updated query object for chaining.

lte(field, value)

Android
iOS
tvOS
ParameterTypeDescription
fieldAssetField

an AssetField to filter by.

valuenumber

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.

Returns:
Query

The updated query object for chaining.

offset(offset)

Android
iOS
tvOS
ParameterTypeDescription
offsetnumber

The number of results to skip.


Skips the specified number of results.

Returns:
Query

The updated query object for chaining.

orderBy(sortDescriptors)

Android
iOS
tvOS
ParameterTypeDescription
sortDescriptorsAssetField | 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.

Returns:
Query

within(field, value)

Android
iOS
tvOS
ParameterTypeDescription
fieldT

an AssetField to filter by.

valueundefined

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.

Returns:
Query

The updated query object for chaining.

Methods

MediaLibrary (next).requestPermissionsAsync(writeOnly, granularPermissions)

Android
iOS
tvOS
ParameterTypeDescription
writeOnly(optional)boolean
Default:false
granularPermissions(optional)GranularPermission[]

A list of GranularPermission values. This parameter has an effect only on Android 13 and newer. By default, expo-media-library will ask for all possible permissions.

When using granular permissions with a custom config plugin configuration, make sure that all the requested permissions are included in the plugin.


Asks the user to grant permissions for accessing media in user's media library.

Returns:
Promise<PermissionResponse>

A promise that fulfils with PermissionResponse object.

Types

AssetFieldValueMap

Android
iOS
tvOS
PropertyTypeDescription
creationTimenumber
-
durationnumber
-
heightnumber
-
mediaTypeMediaType
-
modificationTimenumber
-
widthnumber
-

GranularPermission

Android
iOS
tvOS

Literal Type: string

Acceptable values are: 'audio' | 'photo' | 'video'

SortDescriptor

Android
iOS
tvOS
PropertyTypeDescription
ascending(optional)boolean
-
keyAssetField
-

Enums

AssetField

Android
iOS
tvOS

CREATION_TIME

AssetField.CREATION_TIME = "creationTime"

DURATION

AssetField.DURATION = "duration"

HEIGHT

AssetField.HEIGHT = "height"

MEDIA_TYPE

AssetField.MEDIA_TYPE = "mediaType"

MODIFICATION_TIME

AssetField.MODIFICATION_TIME = "modificationTime"

WIDTH

AssetField.WIDTH = "width"

MediaType

Android
iOS
tvOS

AUDIO

MediaType.AUDIO = "audio"

IMAGE

MediaType.IMAGE = "image"

UNKNOWN

MediaType.UNKNOWN = "unknown"

VIDEO

MediaType.VIDEO = "video"