expo-av vs expo-media-library vs react-native-sound vs react-native-video
Media Playback and Storage Access in React Native
expo-avexpo-media-libraryreact-native-soundreact-native-videoSimilar Packages:

Media Playback and Storage Access in React Native

expo-av, expo-media-library, react-native-sound, and react-native-video are essential tools for handling media in React Native applications, but they serve distinct architectural roles. expo-av and react-native-sound focus on audio playback, while expo-av and react-native-video handle video rendering. expo-media-library stands apart by managing access to the device's photo and media storage rather than playback. Choosing the right combination depends on whether you are using the Expo managed workflow, require advanced video features like DRM, or need to save and retrieve files from the user's gallery.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
expo-av048,1001.3 MB8704 months agoMIT
expo-media-library048,1001.24 MB8703 days agoMIT
react-native-sound02,90994.4 kB2485 months agoMIT
react-native-video07,661954 kB2135 days agoMIT

Media Playback and Storage in React Native: Architecture Compared

Building media features in React Native requires choosing between Expo's unified modules and community-driven native packages. expo-av, expo-media-library, react-native-sound, and react-native-video each solve specific parts of the media puzzle. Let's compare how they handle playback, storage access, and configuration.

๐ŸŽต Audio Playback Implementation

expo-av provides a modern, promise-based API for loading and playing sound files. It works seamlessly in both managed and bare workflows.

// expo-av: Modern async/await API
import { Audio } from 'expo-av';

async function playSound() {
  const { sound } = await Audio.Sound.createAsync(
    require('./assets/sound.mp3')
  );
  await sound.playAsync();
}

react-native-sound uses a callback-based constructor pattern. It is older and requires manual management of the sound instance.

// react-native-sound: Callback-based API
import Sound from 'react-native-sound';

const whoosh = new Sound('whoosh.mp3', Sound.MAIN_BUNDLE, (error) => {
  if (!error) whoosh.play();
});

react-native-video is designed for video, not audio-only. Using it for audio is possible but inefficient as it initializes a video renderer.

// react-native-video: Not intended for audio-only
// Requires a Video component even for audio streams
import Video from 'react-native-video';

// <Video source={{uri: 'audio.mp3'}} />
// Avoid this for pure audio; use expo-av instead.

expo-media-library does not handle playback. It manages storage access. Trying to play media directly with this package will fail.

// expo-media-library: No playback capability
// This package saves or retrieves assets, does not play them
import * as MediaLibrary from 'expo-media-library';

// Use with expo-av to play retrieved assets
// const asset = await MediaLibrary.getAssetAsync(id);

๐Ÿ“น Video Playback Implementation

expo-av includes a <Video> component that covers most standard needs like streaming, local files, and basic controls.

// expo-av: Unified Video component
import { Video } from 'expo-av';

export default function Player() {
  return <Video source={{ uri: 'video.mp4' }} useNativeControls />;
}

react-native-video offers deeper customization for video, including DRM, custom control layers, and background playback configuration.

// react-native-video: Advanced Video component
import Video from 'react-native-video';

export default function Player() {
  return <Video source={{ uri: 'video.mp4' }} controls={true} />;
}

react-native-sound does not support video playback. It is strictly for audio assets.

// react-native-sound: No video support
// Cannot render video streams
import Sound from 'react-native-sound';

// No Video component available

expo-media-library does not play video. It retrieves video assets from the gallery, which you must then pass to a player like expo-av.

// expo-media-library: Retrieves video assets only
import * as MediaLibrary from 'expo-media-library';

// Get video URI, then pass to expo-av Video component
const assets = await MediaLibrary.getAssetsAsync({ mediaType: 'video' });

๐Ÿ—„๏ธ Accessing Device Media Library

expo-media-library is the standard for saving and loading media from the device gallery in Expo projects.

// expo-media-library: Save and load assets
import * as MediaLibrary from 'expo-media-library';

await MediaLibrary.requestPermissionsAsync();
const assets = await MediaLibrary.getAssetsAsync({ first: 10 });

expo-av does not access the gallery directly. It plays media from URIs provided by other modules.

// expo-av: No gallery access
// Requires URI from another source
import { Video } from 'expo-av';

// <Video source={{ uri: '...' }} />
// Must get URI via expo-media-library or network

react-native-video does not access the gallery. It relies on external modules to provide file paths or URIs.

// react-native-video: No gallery access
import Video from 'react-native-video';

// Source must be provided manually
// <Video source={{ uri: filePath }} />

react-native-sound does not access the gallery. It plays bundled assets or network URLs.

// react-native-sound: No gallery access
import Sound from 'react-native-sound';

// Plays from app bundle or network
// new Sound('file.mp3', Sound.MAIN_BUNDLE)

๐Ÿ” Permissions and Native Configuration

expo-av handles permissions automatically in Managed Workflow. In Bare Workflow, it requires config plugins.

// expo-av: Managed Workflow handles permissions
// app.json configuration
{
  "expo": {
    "plugins": ["expo-av"]
  }
}

expo-media-library requires explicit permission requests in code and configuration in app.json for iOS and Android.

// expo-media-library: Explicit permission request
import * as MediaLibrary from 'expo-media-library';

const { status } = await MediaLibrary.requestPermissionsAsync();
// Check status === 'granted'

react-native-video requires manual linking or config plugins in Expo. You must manage native dependencies yourself in bare workflows.

// react-native-video: Manual native config
// Requires pod install for iOS
// Requires gradle changes for Android
// npx pod-install (iOS)

react-native-sound requires manual linking in older React Native versions or config plugins in Expo. It is less integrated than Expo modules.

// react-native-sound: Manual linking
// Often requires react-native-link or manual native setup
// Less seamless than expo-av in Expo projects

๐Ÿค Similarities: Shared Ground Between Packages

While these packages serve different roles, they share common patterns in the React Native ecosystem.

1. โš›๏ธ React Component Integration

  • expo-av and react-native-video both provide React components for rendering media.
  • Both support props for controlling playback state.
// Both use React components for video
// expo-av
import { Video } from 'expo-av';
<Video source={{ uri }} />

// react-native-video
import Video from 'react-native-video';
<Video source={{ uri }} />

2. ๐Ÿ”Š Async Playback Control

  • expo-av and react-native-sound both manage audio lifecycle.
  • Both require cleanup to prevent memory leaks.
// Both require cleanup
// expo-av
await sound.unloadAsync();

// react-native-sound
whoosh.release();

3. ๐Ÿ“ฑ Cross-Platform Support

  • All packages support iOS and Android.
  • All require specific permissions for media access.
// All require permissions
// iOS: Info.plist entries
// Android: AndroidManifest.xml entries

๐Ÿ“Š Summary: Key Capabilities

Featureexpo-avexpo-media-libraryreact-native-soundreact-native-video
Audio Playbackโœ… YesโŒ Noโœ… Yesโš ๏ธ Possible
Video Playbackโœ… YesโŒ NoโŒ Noโœ… Yes
Gallery AccessโŒ Noโœ… YesโŒ NoโŒ No
Expo Managedโœ… Nativeโœ… Nativeโš ๏ธ Config Pluginโš ๏ธ Config Plugin
Advanced Videoโš ๏ธ BasicโŒ NoโŒ Noโœ… Advanced

๐Ÿ’ก The Big Picture

expo-av is the all-rounder ๐Ÿงฐ โ€” best for teams using Expo who need reliable audio and video without native hassle. It covers 90% of use cases.

expo-media-library is the storage manager ๐Ÿ—„๏ธ โ€” essential if your app saves photos or videos to the device. It pairs with expo-av for playback.

react-native-video is the specialist ๐ŸŽฌ โ€” choose this for complex video needs like DRM or custom controls in bare workflows.

react-native-sound is the legacy tool ๐Ÿ•ฐ๏ธ โ€” only use for specific bare workflow needs where expo-av isn't an option. Prefer expo-av for new projects.

Final Thought: For most modern React Native apps, start with expo-av and expo-media-library. Only reach for react-native-video if you hit the limits of Expo's video component.

How to Choose: expo-av vs expo-media-library vs react-native-sound vs react-native-video

  • expo-av:

    Choose expo-av if you are building with Expo Managed Workflow and need a unified solution for both audio and video playback. It offers a consistent API, handles permissions gracefully within the Expo ecosystem, and receives regular updates alongside the SDK. It is the default choice for most standard media playback needs.

  • expo-media-library:

    Choose expo-media-library if your app needs to save images or videos to the device gallery or read existing media from the user's storage. It does not play media; it manages access. Pair this with expo-av if you need to play the media you retrieve.

  • react-native-sound:

    Choose react-native-sound only for legacy bare React Native projects requiring simple sound effects where expo-av cannot be integrated. It is largely considered legacy compared to modern alternatives, so evaluate expo-av or react-native-track-player first for new development.

  • react-native-video:

    Choose react-native-video if you need advanced video capabilities such as DRM support, custom control overlays, or picture-in-picture mode in a bare React Native workflow. It offers more granular control than expo-av but requires more complex native configuration.