CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-expo-media-library

Provides access to user's media library for React Native and Expo applications.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

albums.mddocs/

Album Management

Album creation, management, and asset organization with support for both user-created albums and smart albums (iOS), including comprehensive album operations and platform-specific migration features.

Capabilities

Query Albums

Retrieves all user-created albums with optional smart album inclusion on iOS.

/**
 * Queries for user-created albums with optional smart album inclusion
 * @param options - Album query options (optional)
 * @returns Promise resolving to array of Album objects
 */
function getAlbumsAsync(options?: AlbumsOptions): Promise<Album[]>;

interface AlbumsOptions {
  /** Include smart albums in results - iOS only */
  includeSmartAlbums?: boolean;
}

Usage Examples:

import * as MediaLibrary from "expo-media-library";

// Get all user-created albums
const albums = await MediaLibrary.getAlbumsAsync();
console.log(`Found ${albums.length} albums`);

// Include smart albums (iOS only)
const allAlbums = await MediaLibrary.getAlbumsAsync({
  includeSmartAlbums: true
});

// List album details
albums.forEach(album => {
  console.log(`Album: ${album.title} (${album.assetCount} assets)`);
});

Find Album by Name

Searches for a specific album by its title.

/**
 * Finds album by name
 * @param title - Album name to search for
 * @returns Promise resolving to Album object or null if not found
 */
function getAlbumAsync(title: string): Promise<Album | null>;

Usage Examples:

import * as MediaLibrary from "expo-media-library";

// Find specific album
const myAlbum = await MediaLibrary.getAlbumAsync('My Photos');
if (myAlbum) {
  console.log(`Found album with ${myAlbum.assetCount} assets`);
} else {
  console.log('Album not found');
}

// Check if album exists before operations
const targetAlbum = await MediaLibrary.getAlbumAsync('Screenshots');
if (!targetAlbum) {
  // Create album if it doesn't exist
  const newAlbum = await MediaLibrary.createAlbumAsync('Screenshots');
}

Create Album

Creates a new album with optional initial asset.

/**
 * Creates new album with optional initial asset
 * @param albumName - Name for the new album
 * @param asset - Initial asset or asset ID to add (optional)
 * @param copyAsset - Whether to copy asset instead of moving (Android only, optional)
 * @param initialAssetLocalUri - Local URI for initial asset (optional)
 * @returns Promise resolving to the created Album object
 */
function createAlbumAsync(
  albumName: string,
  asset?: AssetRef,
  copyAsset?: boolean,
  initialAssetLocalUri?: string
): Promise<Album>;

Usage Examples:

import * as MediaLibrary from "expo-media-library";

// Create empty album
const emptyAlbum = await MediaLibrary.createAlbumAsync('My New Album');

// Create album with initial asset
const photos = await MediaLibrary.getAssetsAsync({ first: 1 });
const albumWithPhoto = await MediaLibrary.createAlbumAsync(
  'Photo Album',
  photos.assets[0]
);

// Create album with asset copy (Android)
const copiedAlbum = await MediaLibrary.createAlbumAsync(
  'Copied Photos',
  photos.assets[0],
  true // Copy instead of move on Android
);

// Create album with local URI
const savedPhoto = await MediaLibrary.createAssetAsync('file:///path/to/photo.jpg');
const albumFromUri = await MediaLibrary.createAlbumAsync(
  'Saved Photos',
  savedPhoto,
  false,
  'file:///path/to/photo.jpg'
);

Delete Albums

Deletes one or more albums from the media library.

/**
 * Deletes albums from the media library
 * @param albums - Single album or array of albums/album IDs to delete
 * @param assetRemove - Also delete contained assets (iOS only, optional)
 * @returns Promise resolving to boolean indicating success
 */
function deleteAlbumsAsync(
  albums: AlbumRef[] | AlbumRef,
  assetRemove?: boolean
): Promise<boolean>;

Usage Examples:

import * as MediaLibrary from "expo-media-library";

// Delete single album
const album = await MediaLibrary.getAlbumAsync('Old Album');
if (album) {
  const success = await MediaLibrary.deleteAlbumsAsync(album);
  console.log(`Delete ${success ? 'successful' : 'failed'}`);
}

// Delete multiple albums
const allAlbums = await MediaLibrary.getAlbumsAsync();
const emptyAlbums = allAlbums.filter(album => album.assetCount === 0);
const deleteSuccess = await MediaLibrary.deleteAlbumsAsync(emptyAlbums);

// Delete album and its assets (iOS only)
const albumToDelete = await MediaLibrary.getAlbumAsync('Temporary Album');
if (albumToDelete) {
  await MediaLibrary.deleteAlbumsAsync(albumToDelete, true); // Delete assets too
}

// Delete by album IDs
const albumIds = ['album-id-1', 'album-id-2'];
await MediaLibrary.deleteAlbumsAsync(albumIds);

Add Assets to Album

Adds one or more assets to an existing album.

/**
 * Adds assets to an album
 * @param assets - Single asset or array of assets/asset IDs to add
 * @param album - Target album or album ID
 * @param copy - Copy assets instead of moving (Android only, optional)
 * @returns Promise resolving to boolean indicating success
 */
function addAssetsToAlbumAsync(
  assets: AssetRef[] | AssetRef,
  album: AlbumRef,
  copy?: boolean
): Promise<boolean>;

Usage Examples:

import * as MediaLibrary from "expo-media-library";

// Add single asset to album
const photos = await MediaLibrary.getAssetsAsync({ 
  mediaType: MediaLibrary.MediaType.photo,
  first: 1 
});
const album = await MediaLibrary.getAlbumAsync('My Photos');
if (album && photos.assets.length > 0) {
  const added = await MediaLibrary.addAssetsToAlbumAsync(photos.assets[0], album);
}

// Add multiple assets
const recentPhotos = await MediaLibrary.getAssetsAsync({
  mediaType: MediaLibrary.MediaType.photo,
  first: 10,
  sortBy: [MediaLibrary.SortBy.creationTime, false]
});
const photoAlbum = await MediaLibrary.getAlbumAsync('Recent Photos');
if (photoAlbum) {
  await MediaLibrary.addAssetsToAlbumAsync(recentPhotos.assets, photoAlbum);
}

// Copy assets instead of moving (Android)
await MediaLibrary.addAssetsToAlbumAsync(
  recentPhotos.assets,
  photoAlbum,
  true // Copy on Android
);

// Add newly created asset
const newAsset = await MediaLibrary.createAssetAsync('file:///path/to/new/photo.jpg');
const targetAlbum = await MediaLibrary.getAlbumAsync('New Photos');
if (targetAlbum) {
  await MediaLibrary.addAssetsToAlbumAsync(newAsset, targetAlbum);
}

Remove Assets from Album

Removes assets from an album without deleting the assets themselves.

/**
 * Removes assets from album without deleting the assets
 * @param assets - Single asset or array of assets/asset IDs to remove
 * @param album - Source album or album ID
 * @returns Promise resolving to boolean indicating success
 */
function removeAssetsFromAlbumAsync(
  assets: AssetRef[] | AssetRef,
  album: AlbumRef
): Promise<boolean>;

Usage Examples:

import * as MediaLibrary from "expo-media-library";

// Remove single asset from album
const album = await MediaLibrary.getAlbumAsync('My Album');
const albumAssets = await MediaLibrary.getAssetsAsync({ 
  album: album,
  first: 1 
});
if (album && albumAssets.assets.length > 0) {
  await MediaLibrary.removeAssetsFromAlbumAsync(albumAssets.assets[0], album);
}

// Remove multiple assets
const assetsToRemove = await MediaLibrary.getAssetsAsync({
  album: album,
  first: 5
});
await MediaLibrary.removeAssetsFromAlbumAsync(assetsToRemove.assets, album);

// Remove assets by ID
const assetIds = ['asset-1', 'asset-2', 'asset-3'];
await MediaLibrary.removeAssetsFromAlbumAsync(assetIds, album);

// Clean up album by removing old assets
const oldAssets = await MediaLibrary.getAssetsAsync({
  album: album,
  createdBefore: new Date('2022-01-01'),
  first: 100
});
if (oldAssets.assets.length > 0) {
  await MediaLibrary.removeAssetsFromAlbumAsync(oldAssets.assets, album);
}

Platform-Specific Features

iOS Moments

Access to moment albums that group assets by location and time.

/**
 * Fetches moments (asset groups by place/time)
 * @platform ios
 * @returns Promise resolving to array of moment Album objects
 */
function getMomentsAsync(): Promise<Album[]>;

Usage Examples:

import * as MediaLibrary from "expo-media-library";
import { Platform } from "react-native";

if (Platform.OS === 'ios') {
  const moments = await MediaLibrary.getMomentsAsync();
  
  moments.forEach(moment => {
    console.log(`Moment: ${moment.title}`);
    console.log(`Assets: ${moment.assetCount}`);
    console.log(`Period: ${new Date(moment.startTime)} - ${new Date(moment.endTime)}`);
    if (moment.locationNames) {
      console.log(`Locations: ${moment.locationNames.join(', ')}`);
    }
  });
}

Android Album Migration

Support for migrating albums to scoped storage directories on Android R+.

/**
 * Checks if album needs migration to scoped storage
 * @platform android R+
 * @param album - Album or album ID to check
 * @returns Promise resolving to boolean indicating if migration is needed
 */
function albumNeedsMigrationAsync(album: AlbumRef): Promise<boolean>;

/**
 * Migrates album to scoped storage directories
 * @platform android R+
 * @param album - Album or album ID to migrate
 * @returns Promise resolving when migration is complete
 */
function migrateAlbumIfNeededAsync(album: AlbumRef): Promise<void>;

Usage Examples:

import * as MediaLibrary from "expo-media-library";
import { Platform } from "react-native";

if (Platform.OS === 'android' && Platform.Version >= 30) {
  const albums = await MediaLibrary.getAlbumsAsync();
  
  for (const album of albums) {
    const needsMigration = await MediaLibrary.albumNeedsMigrationAsync(album);
    if (needsMigration) {
      console.log(`Migrating album: ${album.title}`);
      await MediaLibrary.migrateAlbumIfNeededAsync(album);
      console.log('Migration complete');
    }
  }
}

Types

interface Album {
  /** Unique identifier for the album */
  id: string;
  /** Album title/name */
  title: string;
  /** Estimated number of assets in the album */
  assetCount: number;
  /** Album type - iOS only */
  type?: AlbumType;
  /** Start time for moment albums - iOS only */
  startTime: number;
  /** End time for moment albums - iOS only */
  endTime: number;
  /** Approximate location for moment albums - iOS only */
  approximateLocation?: Location;
  /** Location names for moment albums - iOS only */
  locationNames?: string[];
}

/**
 * Album types available on iOS
 * @platform ios
 */
type AlbumType = 
  | 'album'        // User-created album
  | 'moment'       // Moment album (grouped by time/location)
  | 'smartAlbum';  // Smart album (Favorites, Screenshots, etc.)

interface Location {
  /** Latitude coordinate */
  latitude: number;
  /** Longitude coordinate */
  longitude: number;
  /** Altitude in meters (optional) */
  altitude?: number;
  /** Accuracy in meters (optional) */
  accuracy?: number;
}

type AlbumRef = Album | string;

type AssetRef = Asset | string;

Platform-Specific Behavior

iOS

  • Smart Albums: Built-in albums like Favorites, Screenshots, Recently Added
  • Moments: Automatic grouping by location and time with metadata
  • Album Types: Distinction between user albums, moments, and smart albums
  • Asset Deletion: Option to delete assets when deleting albums

Android

  • Scoped Storage: Full support for Android R+ scoped storage requirements
  • Migration: Automatic migration of albums to scoped directories
  • Copy vs Move: Control over whether assets are copied or moved between albums
  • Album IDs: Direct album references through asset albumId property

Web

  • Limited Support: Basic album operations through browser file system APIs
  • No Advanced Features: Moments, smart albums, and migration not available

docs

albums.md

assets.md

events.md

index.md

permissions.md

tile.json