Skip to content

Repository files navigation

plex-sdk

npmnpmnpmVitest

semantic-releaseCommitizen friendly

TypeScript SDK for Plex and Plex Media Server APIs with full type safety, payload response simplification and comprehensive coverage

Features

  • 🔐 Secure Authentication: Full support for Plex.tv authentication
  • 🎯 Type Safety: Complete TypeScript definitions for all API responses
  • 🚀 Modern ESM: Built as a modern ES module with tree-shaking support
  • 📦 Lightweight: Minified bundle with zero runtime dependencies
  • 🧪 Well Tested: Comprehensive test suite with 97%+ coverage
  • 🎬 Media Server Integration: Direct access to your Plex Media Server
  • 🔍 Search Capabilities: Powerful search across movies, TV shows, and more

Installation

Using npm

npm install plex-sdk

Using yarn

yarn add plex-sdk

Using pnpm

pnpm add plex-sdk

From source

git clone git@github.com:nass600/plex-sdk.git
cd plex-sdk
npm install
npm run build

API Response Simplification

This SDK simplifies Plex API responses by automatically extracting the relevant data from the nested MediaContainer structure. Instead of dealing with complex nested objects, you get clean, direct access to the data you need.

Before (Raw Plex API):

{
"MediaContainer": {
"size": 1,
"Directory": [
{
"title": "Movies",
"type": "movie",
"key": "/library/sections/1"
}
]
}
}

After (Simplified SDK Response):

[
{
"title": "Movies",
"type": "movie",
"key": "/library/sections/1"
}
]

The SDK handles the MediaContainer extraction automatically, so you can focus on working with your data directly.

Quick Start

1. Get Your Plex Token

First, you need to get your Plex token. You can find it by:

  1. Open your Plex web app in your browser
  2. Open Developer Tools (F12 or right-click → Inspect)
  3. Go to the Network tab
  4. Refresh the page or navigate to any section
  5. Look for requests to plex.tv - the token will be in the request headers as X-Plex-Token
  6. Copy the token value (it's a long string of letters and numbers)

Alternatively, you can find it in your Plex app settings or by examining the network requests in any Plex client.

2. Initialize the Plex Client

import{PlexClient}from'plex-sdk'constclient=newPlexClient('your-plex-token-here',{device: 'My App',product: 'My Plex App',version: '1.0.0',})

3. Server Selection

The SDK provides two ways to connect to your Plex Media Server:

A. List All Resources and select a server

First, you can explore all available resources to see what's available:

constresources=awaitclient.getResources()// Display all resources with their typesresources.forEach(resource=>{console.log(`${resource.name}: ${resource.provides?.join(', ')}`)})// Filter to find only serversconstservers=resources.filter(resource=>resource.provides?.includes('server'))// Query any resourceconsthubs=servers[0].hubs.all()

B. Direct Server Connection

Once you know your server name, you can connect directly:

// Connect by server name using the first connection availableconstserver=awaitclient.getServer('My Plex Server')// Or filtering by connection preferencesconstserver=awaitclient.getServer('My Plex Server',{local: true,// Prefer local connectionssecure: true,// Prefer secure connectionsrelay: false,// Avoid relay connections})// Query any resourceconsthubs=server.hubs.all()

4. Advanced Connection Filtering

The SDK supports advanced connection filtering with both exact matching and regex patterns:

// Exact matching (existing behavior)constserver=awaitclient.getServer('My Plex Server',{address: '192.168.1.100',protocol: 'https',local: true,})// Regex pattern matching (new feature)constserver=awaitclient.getServer('My Plex Server',{address: /192\.168\.1\.\d+/,// Match any IP in 192.168.1.x rangeprotocol: /^https?$/,// Match http or httpsport: /^324\d+$/,// Match ports starting with 324})// Mixed exact and regex matchingconstserver=awaitclient.getServer('My Plex Server',{local: true,// Exact boolean matchaddress: /192\.168\.\d+\.\d+/,// Regex for local network IPsprotocol: 'https',// Exact protocol match})// Partial string matching with regexconstserver=awaitclient.getServer('My Plex Server',{address: /example\.com/,// Match any address containing 'example.com'uri: /https:\/\/.*\.local/,// Match HTTPS URIs ending with '.local'})

Available filter properties:

  • address - Server address (supports regex patterns)
  • protocol - Connection protocol (http/https)
  • port - Port number
  • uri - Full connection URI
  • local - Whether connection is local
  • relay - Whether connection uses relay
  • IPv6 - Whether connection uses IPv6

Usage Examples

Search for a specific movie

Here's a comprehensive example showing how to search for a specific movie:

import{PlexClient,SearchType}from'plex-sdk'asyncfunctionsearchForMovie(movieTitle: string){// 1. Initialize the Plex client with your tokenconstclient=newPlexClient('your-plex-token-here',{device: 'Movie Search App',product: 'Plex Movie Finder',version: '1.0.0',})try{// 2. Connect directly to your server by nameconstserver=awaitclient.getServer('My Plex Server')console.log(`✅ Connected to server: ${server.name}`)// 5. Search for the movieconstsearchResults=awaitserver.library.search({query: movieTitle,// The query text will be normalized internallysearchTypes: [SearchType.MOVIES],})if(searchResults.length===0){console.log(`❌ No movies found for "${movieTitle}"`)returnnull}// 6. Display resultsconsole.log(`🎬 Found ${searchResults.length} movie(s) for "${movieTitle}":`)searchResults.forEach((movie,index)=>{console.log(`\n${index+1}. ${movie.title} (${movie.year})`)console.log(` Rating: ${movie.rating}/5`)console.log(` Duration: ${Math.round(movie.duration/60000)} minutes`)console.log(` Summary: ${movie.summary?.substring(0,100)}...`)if(movie.Role&&movie.Role.length>0){console.log(` Cast: ${movie.Role.slice(0,3).map(role=>role.tag).join(', ')}`)}})returnsearchResults[0]// Return the first result}catch(error){console.error('❌ Error searching for movie:',error)throwerror}}// UsagesearchForMovie('The Dark Knight').then(movie=>{if(movie){console.log(`\n🎉 Successfully found: ${movie.title}`)}}).catch(error=>{console.error('Failed to search for movie:',error)})

Browse Your Media Library

asyncfunctionbrowseLibrary(){constclient=newPlexClient('your-plex-token-here',{device: 'Library Browser',product: 'Plex Library Explorer',version: '1.0.0',})constserver=awaitclient.getServer('My Plex Server')// Get all librariesconstlibraries=awaitserver.library.all()console.log('📚 Available libraries:')libraries.forEach(lib=>{console.log(` - ${lib.title} (${lib.type})`)})// Get all movies from the first libraryif(libraries.length>0){constmovies=awaitserver.library.allItems(libraries[0].key)console.log(`\n🎬 Movies in ${libraries[0].title}:`)movies.slice(0,5).forEach(movie=>{console.log(` - ${movie.title} (${movie.year})`)})}}

Get Movie Metadata

asyncfunctiongetMovieDetails(movieId: string){constclient=newPlexClient('your-plex-token-here',{device: 'Movie Details App',product: 'Plex Movie Info',version: '1.0.0',})constserver=awaitclient.getServer('My Plex Server')// Get detailed metadata for a specific movieconstmovie=awaitserver.metadata.one(movieId)console.log(`🎬 ${movie.title} (${movie.year})`)console.log(`📝 ${movie.summary}`)console.log(`⭐ Rating: ${movie.rating}/5`)console.log(`⏱️ Duration: ${Math.round(movie.duration/60000)} minutes`)if(movie.Director){console.log(`🎭 Director: ${movie.Director.map(d=>d.tag).join(', ')}`)}if(movie.Role){console.log(`👥 Cast: ${movie.Role.slice(0,5).map(role=>role.tag).join(', ')}`)}if(movie.Genre){console.log(`🎭 Genres: ${movie.Genre.map(g=>g.tag).join(', ')}`)}}

Browse Hubs

asyncfunctionbrowseHubs(){constclient=newPlexClient('your-plex-token-here',{device: 'Hub Browser',product: 'Plex Hub Explorer',version: '1.0.0',})constserver=awaitclient.getServer('My Plex Server')// Get all hubsconsthubs=awaitserver.hubs.all()console.log('🏠 Available hubs:')hubs.forEach(hub=>{console.log(` - ${hub.title} (${hub.type})`)})}

API Reference

PlexClient

The main client for interacting with Plex.tv services.

constclient=newPlexClient(token: string,{device?: string,// Device name (default: 'Node.js')product?: string,// Product name (default: 'Plex SDK')version?: string,// Version string (default: '1.0')platform?: string,// Platform name (default: 'Node.js')clientIdentifier?: string// Client identifier (default: 'plex-sdk')})

Methods

  • getResources(): Promise<PlexResource[]> - Get available Plex servers
  • getServer(resourceName: string, connectionsFilter?: PlexConnectionFilter): Promise<PlexServer> - Create a server instance with advanced filtering

PlexServer

Represents a connection to a Plex Media Server.

Properties

  • name: string - Server name
  • hubs: Hubs - Access to server hubs
  • library: Library - Access to media library
  • metadata: Metadata - Access to metadata

Methods

  • search(query: string): Promise<SearchResult[]> - Search across all media

Library

Provides access to the media library.

Methods

  • all(): Promise<Directory[]> - Get all libraries
  • allItems(sectionId: string, params?: QueryParams): Promise<Metadata[]> - Get all items from a library
  • search(params: SearchParams): Promise<SearchResult[]> - Search within libraries

Search Parameters

interfaceSearchParams{query: string// Search query (required)searchTypes: SearchType[]// Types to search (MOVIES, TV, etc.)}

Connection Filtering

typePlexConnectionFilter=Partial<{[KinkeyofPlexConnection]: PlexConnection[K]|RegExp}>// Example usage:constfilter: PlexConnectionFilter={address: /192\.168\.1\.\d+/,// Regex patternprotocol: 'https',// Exact matchlocal: true,// Boolean matchport: /^324\d+$/,// Regex pattern}

Error Handling

The SDK provides comprehensive error handling:

try{constserver=awaitclient.getServer('My Plex Server')}catch(error){if(error.message.includes('Server not found')){console.error('❌ Plex server not found - check your server name')}elseif(error.message.includes('Network error')){console.error('❌ Network connection failed - check your internet connection')}elseif(error.message.includes('Unauthorized')){console.error('❌ Invalid token - check your Plex token')}else{console.error('❌ Unexpected error:',error.message)}}

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Changelog

See CHANGELOG file for more details.

License

This project is licensed under the MIT License - see the LICENSE file for details

Authors

About

Typescript SDK for Plex API

Resources

Stars

9 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages