A powerful React Native library for accessing local music files and getting full metadata. Built with React Native's New Architecture (TurboModules) for optimal performance.
- 🎵 Rich Metadata - Access local music with full metadata including lyrics, bitrate, sample rate, and more
- 🚀 TurboModules - Built with React Native's New Architecture for maximum performance
- 📄 Pagination - Cursor-based pagination for efficiently handling large music collections
- 🔍 Flexible Sorting - Multiple sorting options for tracks, albums, and artists
- 📁 Directory Filtering - Filter tracks by specific directories (Android)
- 🔄 TypeScript - Full type definitions and type safety
- 🎨 Album Artwork - Support for album artwork and cover images
- 🤖 Android - Full native Android implementation
- 🍎 iOS - Full native iOS implementation via MediaPlayer framework
npm install @nodefinity/react-native-music-library
# or
yarn add @nodefinity/react-native-music-libraryAndroid — add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />iOS — add to Info.plist:
<key>NSAppleMusicUsageDescription</key>
<string>This app needs access to your music library.</string>import {
getTracksAsync,
getAlbumsAsync,
getArtistsAsync,
} from '@nodefinity/react-native-music-library';
// Get first 20 tracks sorted by title
const result = await getTracksAsync({ sortBy: ['title', true] });
console.log(result.items); // Track[]
console.log(result.hasNextPage); // boolean
console.log(result.endCursor); // string | undefined
// Get next page
const nextPage = await getTracksAsync({
sortBy: ['title', true],
first: 20,
after: result.endCursor,
});Returns a paginated list of tracks from the music library.
getTracksAsync(options?: TrackOptions): Promise<PaginatedResult<Track>>TrackOptions
| Property | Type | Default | Description |
|---|---|---|---|
first |
number |
20 |
Max number of items to return |
after |
string |
— | Cursor from previous page's endCursor |
sortBy |
TrackSortByKey | [TrackSortByKey, boolean] | (...)[] |
'default' |
Sort key, or tuple [key, ascending] |
directory |
string |
— | Filter by directory path (Android only) |
TrackSortByKey: 'default' \| 'title' \| 'artist' \| 'album' \| 'duration' \| 'createdAt' \| 'modifiedAt' \| 'fileSize'
Returns detailed audio metadata for a single track.
getTrackMetadataAsync(trackId: string): Promise<TrackMetadata>Returns all tracks in an album (no pagination).
getTracksByAlbumAsync(albumId: string): Promise<Track[]>Returns a paginated list of tracks by an artist.
getTracksByArtistAsync(artistId: string, options?: TrackOptions): Promise<PaginatedResult<Track>>Returns a paginated list of albums.
getAlbumsAsync(options?: AlbumOptions): Promise<PaginatedResult<Album>>AlbumOptions
| Property | Type | Default | Description |
|---|---|---|---|
first |
number |
20 |
Max number of items to return |
after |
string |
— | Cursor from previous page's endCursor |
sortBy |
AlbumSortByKey | [AlbumSortByKey, boolean] | (...)[] |
'default' |
Sort key, or tuple [key, ascending] |
AlbumSortByKey: 'default' \| 'title' \| 'artist' \| 'trackCount' \| 'year'
Returns all albums by an artist (no pagination).
getAlbumsByArtistAsync(artistId: string): Promise<Album[]>Returns a paginated list of artists.
getArtistsAsync(options?: ArtistOptions): Promise<PaginatedResult<Artist>>ArtistOptions
| Property | Type | Default | Description |
|---|---|---|---|
first |
number |
20 |
Max number of items to return |
after |
string |
— | Cursor from previous page's endCursor |
sortBy |
ArtistSortByKey | [ArtistSortByKey, boolean] | (...)[] |
'default' |
Sort key, or tuple [key, ascending] |
ArtistSortByKey: 'default' \| 'title' \| 'trackCount' \| 'albumCount'
| Field | Type | Description |
|---|---|---|
id |
string |
Unique identifier |
title |
string |
Track title |
artist |
string |
Artist name |
artwork |
string? |
Artwork file URI (may be undefined) |
album |
string |
Album name |
duration |
number |
Duration in seconds |
url |
string |
File URI |
createdAt |
number |
Unix timestamp (seconds) |
modifiedAt |
number |
Unix timestamp (seconds) |
fileSize |
number |
File size in bytes |
| Field | Type | Description |
|---|---|---|
id |
string |
Track ID |
duration |
number |
Duration in seconds |
bitrate |
number |
Bitrate in kbps |
sampleRate |
number |
Sample rate in Hz |
channels |
string |
Number of audio channels |
format |
string |
Audio format (e.g. "AAC", "MP3") |
title |
string |
Title tag |
artist |
string |
Artist tag |
album |
string |
Album tag |
year |
number |
Release year |
genre |
string |
Genre tag |
track |
number |
Track number |
disc |
number |
Disc number |
composer |
string |
Composer tag |
lyricist |
string |
Lyricist tag |
lyrics |
string |
Embedded lyrics |
albumArtist |
string |
Album artist tag |
comment |
string |
Comment tag |
| Field | Type | Description |
|---|---|---|
id |
string |
Unique identifier |
title |
string |
Album name |
artist |
string |
Primary artist |
artwork |
string? |
Artwork URI (may be undefined) |
trackCount |
number |
Number of tracks |
year |
number? |
Release year |
| Field | Type | Description |
|---|---|---|
id |
string |
Unique identifier |
title |
string |
Artist name |
albumCount |
number |
Number of albums |
trackCount |
number |
Total number of tracks |
| Field | Type | Description |
|---|---|---|
items |
T[] |
Array of results |
hasNextPage |
boolean |
Whether more items are available |
endCursor |
string? |
Pass to after to fetch next page |
totalCount |
number? |
Total count (may be expensive to compute) |
async function fetchAllTracks() {
const allTracks = [];
let cursor: string | undefined;
do {
const result = await getTracksAsync({ first: 50, after: cursor });
allTracks.push(...result.items);
cursor = result.hasNextPage ? result.endCursor : undefined;
} while (cursor);
return allTracks;
}See CONTRIBUTING.md for details.
MIT License - see LICENSE for details.




