npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@juanpprieto/lexicon-client

v1.0.2

Published

TypeScript-first client for Lexicon DJ's local REST API with comprehensive type safety and unified control interface

Readme

@juanpprieto/lexicon-client

CI npm version License Node.js

TypeScript-first client for Lexicon DJ's REST API with comprehensive type safety and unified control interface

Build professional DJ applications with confidence. This library provides complete type-safe access to Lexicon DJ's local API, with automatic validation, intelligent error handling, and a unified control interface for all DJ operations.

What is Lexicon DJ?

Lexicon DJ is professional DJ software for managing music libraries, creating playlists, and performing live DJ sets. It provides a built-in REST API that allows developers to programmatically control the software, access music metadata, and integrate DJ functionality into custom applications.

Perfect for building:

  • 🎛️ Custom DJ controllers and interfaces
  • 📊 Music library analysis and management tools
  • 🤖 Automated playlist generation and DJ workflows
  • 📱 Mobile DJ applications and remote controls

✨ Key Features

  • 🔒 Complete Type Safety - Full TypeScript support with automatic type inference
  • ⚡ Zero Configuration - Works out of the box with sensible defaults
  • 🎛️ Unified Control API - 128+ DJ operations under client.control.*
  • 📊 Comprehensive Library Management - Tracks, playlists, tags with full CRUD operations
  • 🚀 Modern Architecture - Built with Zod validation, neverthrow error handling, and undici HTTP client
  • 🧪 Production Ready - Extensive test suite with both unit and integration tests

⚡ Requirements

This library requires Lexicon DJ to be installed and running with the Local API enabled.

1. Install Lexicon DJ

Download and install Lexicon DJ - professional DJ software with local API support.

2. Enable the Local API

⚠️ CRITICAL: The Lexicon Local API is disabled by default and must be enabled manually:

  1. Open Lexicon DJ
  2. Go to Settings → Integrations
  3. Enable "Local API"
  4. Verify it's running on localhost:48624

The Local API is a REST API that you can send requests to as long as Lexicon is running. See the official API documentation for complete details.

3. Verify Connection

# Test if the API is accessible
curl http://localhost:48624/api/tracks?limit=1

🚀 Quick Start

Installation

npm install @juanpprieto/lexicon-client

Basic Usage

import { createClient } from '@juanpprieto/lexicon-client'

// Connect to Lexicon DJ (localhost:48624)
const client = createClient()

// List tracks from your library
const tracks = await client.tracks.list({ limit: 10 })
if (tracks.isOk()) {
  console.log(`Found ${tracks.value.tracks.length} tracks`)
  tracks.value.tracks.forEach(track => {
    console.log(`${track.artist} - ${track.title}`)
  })
}

// Control playback
await client.control.player.play()
await client.control.player.pause()

⚠️ Important: This library uses functional error handling. API methods return Result<T, E> instead of throwing errors. Always check .isOk() before accessing data.

🎮 Try the Demos

Learn by example with interactive demos that show exactly how to use the library:

React + Vite Demo (Web Applications)

cd demo/react-vite
npm install && npm run demo

Perfect for building web DJ applications with modern React.

Node.js Demo (Scripts & Backend)

cd demo/node-script
npm install && npm run demo

Perfect for automation scripts and backend DJ tools.

Both demos include:

  • 🔌 Connection testing
  • 📚 API examples for all namespaces
  • 🎛️ Player control demonstrations
  • 📋 AI documentation access examples

📚 API Documentation

Library Management

Tracks API

// List tracks with pagination
const tracks = await client.tracks.list({ limit: 25 })
if (tracks.isOk()) {
  console.log(`Found ${tracks.value.tracks.length} tracks`)
}

// Search tracks by genre
const houseTracks = await client.tracks.search({
  filter: { genre: 'house' },
  limit: 10,
})

// Get a specific track
const track = await client.tracks.get({ id: 123 })
if (track.isOk()) {
  console.log(`${track.value.artist} - ${track.value.title}`)
}

Playlists API

// List all playlists
const playlists = await client.playlists.list()
if (playlists.isOk()) {
  console.log(`Found ${playlists.value.playlists.length} playlists`)
}

// Get a specific playlist
const playlist = await client.playlists.get({ id: 1 })
if (playlist.isOk()) {
  console.log(`Playlist: ${playlist.value.name}`)
  console.log(`Tracks: ${playlist.value.trackIds?.length || 0}`)
}

Tags API

// List all tags and categories
const tagsResult = await client.tags.list()
if (tagsResult.isOk()) {
  const { tags, categories } = tagsResult.value
  console.log(`Found ${tags.length} tags in ${categories.length} categories`)
}

// Get a specific tag
const tag = await client.tags.get({ id: 1 })
if (tag.isOk()) {
  console.log(`Tag: ${tag.value.label}`)
}

Player Control API

// Basic playback control
await client.control.player.play()
await client.control.player.pause()
await client.control.player.stop()

// Get current player state
const state = await client.control.player.getCurrentState()
if (state.isOk()) {
  console.log(`Playing: ${state.value.currentTrack?.title}`)
  console.log(`Progress: ${Math.round(state.value.progress * 100)}%`)
}

// Seek to position
await client.control.player.seek({ progress: 0.5 }) // 50% through track

🔧 Advanced Usage

Advanced Track Operations

// Search tracks with complex filters
const tracks = await client.tracks.search({
  genre: ['house', 'techno'],
  bpmMin: 120,
  bpmMax: 140,
  rating: { min: 4 },
  limit: 50,
})

// Update track metadata
await client.tracks.update({
  id: 123,
  edits: {
    rating: 5,
    energy: '+1',
    tags: [1, 2, 3],
  },
})

// Memory-efficient iteration over large libraries
for await (const track of client.tracks.iterate({ genre: 'house' })) {
  console.log(`${track.artist} - ${track.title}`)
}

Advanced Playlist Management

// Create smart playlists with rules
const smartPlaylist = await client.playlists.create({
  name: 'High Energy House',
  type: 'smart',
  smartlist: {
    rules: [
      { field: 'genre', operator: 'is', value: 'house' },
      { field: 'energy', operator: 'greater_than', value: 7 },
    ],
  },
})

// Add tracks to existing playlist
if (playlist.isOk()) {
  await client.playlists.addTracks({
    id: playlist.value.id,
    trackIds: [1, 2, 3],
    index: 0, // Insert at beginning
  })
}

Advanced Player Control

// Advanced DJ features
await client.control.player.hotcue.trigger({ index: 1 })
await client.control.player.loop.create({ amount: 4 })
await client.control.player.jump.beats({ beats: 16 })
await client.control.player.tempomarker.doubleBpm()

// Interface control
await client.control.appearance.toggleTheme()
await client.control.navigation.toggleSidebar()
await client.control.trackBrowser.analyze()

Advanced Tag Management

// Create tag categories with colors
const category = await client.tagCategories.create({
  name: 'Mood',
  color: '#FF6B6B',
})

// Create tags within categories
const tag = await client.tags.create({
  label: 'Energetic',
  categoryId: category.value.id,
  position: 0,
})

Error Handling with neverthrow

import { match } from 'ts-pattern'

const result = await client.tracks.get({ id: 1 })

match(result)
  .with({ isOk: () => true }, ({ value: track }) => {
    console.log(`Found: ${track.artist} - ${track.title}`)
  })
  .with({ isErr: () => true }, ({ error }) => {
    match(error)
      .with({ type: 'NotFound' }, () => {
        console.log('Track not found')
      })
      .with({ type: 'NetworkError' }, () => {
        console.log('Connection failed - is Lexicon DJ running?')
      })
      .with({ type: 'ValidationError' }, err => {
        console.log(`Invalid request: ${err.message}`)
      })
      .otherwise(() => {
        console.log(`Unexpected error: ${error.message}`)
      })
  })

Batch Operations with Queue Management

import PQueue from 'p-queue'

// Built-in concurrency management prevents API overload
const queue = new PQueue({ concurrency: 5 })

// Process large track collections efficiently
const trackIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const tracks = await Promise.all(
  trackIds.map(id => queue.add(() => client.tracks.get({ id })))
)

// Filter successful results
const validTracks = tracks
  .filter(result => result.isOk())
  .map(result => result.value)

console.log(
  `Successfully loaded ${validTracks.length}/${trackIds.length} tracks`
)

Custom Configuration

import { createClient } from '@juanpprieto/lexicon-client'

const client = createClient({
  baseUrl: 'http://localhost:48624', // Custom Lexicon API URL
  timeout: 30000, // 30 second timeout
  retries: 3, // Retry failed requests
  logger: {
    level: 'debug', // Enable debug logging
    pretty: true, // Pretty-print logs
  },
})

🏗️ TypeScript Integration

Automatic Type Inference

// No manual type annotations needed
const client = createClient() // → LexiconClient

const tracks = await client.tracks.search({
  genre: 'house',
  bpmMin: 128,
}) // → Result<PaginatedTracksResponse, ApiError>

if (tracks.isOk()) {
  tracks.value.tracks.forEach(track => {
    // track is automatically inferred as Track
    console.log(track.artist) // Full IntelliSense support
  })
}

Custom Type Guards

import { type Track } from '@juanpprieto/lexicon-client'

function isHighEnergyTrack(track: Track): boolean {
  return track.energy >= 8 && track.bpm >= 128
}

const tracks = await client.tracks.list()
if (tracks.isOk()) {
  const highEnergyTracks = tracks.value.tracks.filter(isHighEnergyTrack)
  console.log(`Found ${highEnergyTracks.length} high-energy tracks`)
}

🤖 AI-Friendly Documentation

For AI Tools and Development

# Copy AI documentation to your project
npx @juanpprieto/lexicon-client copy-ai-docs

This creates:

  • docs/lexicon-client-llms.txt - Comprehensive API documentation for AI prompts
  • docs/lexicon-client-claude.md - Development context for Claude Code sessions

Usage with AI tools:

"Please read docs/lexicon-client-llms.txt for complete API context and examples"

Alternative: Point AI directly to node_modules:

"Reference node_modules/@juanpprieto/lexicon-client/llms.txt for API documentation"

🧪 Testing

Running Tests

# All tests
npm test

# Unit tests only
npm run test:unit

# Integration tests (requires running Lexicon DJ)
npm run test:integration

# Coverage report
npm run test:coverage

# Watch mode for development
npm run test:watch

Integration Test Requirements

Integration tests require a running Lexicon DJ instance with the Local API enabled:

  1. Open Lexicon DJ
  2. Go to Settings → Integrations
  3. Enable "Local API"
  4. Run npm run lexicon:check to verify connection

📦 Publishing & Releases

This package uses Changesets for version management:

# Add a changeset for your changes
npm run changeset

# Release (maintainers only)
npm run release

Automated Releases

  • GitHub Actions handle automated testing and publishing
  • Semantic versioning based on changeset types
  • NPM provenance for supply chain security
  • GitHub releases with automatically generated changelogs

🛡️ Security

Vulnerability Reporting

If you discover a security vulnerability, please report it privately via Security Advisories.

Supply Chain Security

  • NPM Provenance - All published packages include build provenance
  • SLSA Level 3 - Supply chain security attestation
  • Dependency Scanning - Automated vulnerability detection
  • CodeQL Analysis - Static security analysis

🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines.

Development Setup

# Clone and install
git clone https://github.com/juanpprieto/lexicon-client.git
cd lexicon-client
npm install

# Run quality checks
npm run validate

# Start development
npm run dev

Project Structure

src/
├── client/          # HTTP client and namespace implementations
├── schemas/         # Zod validation schemas (modular structure)
├── types/           # TypeScript type definitions
├── utils/           # Shared utilities
└── __tests__/       # Comprehensive test suite

📋 API Reference

| Namespace | Methods | Description | | ---------------- | ------- | ------------------------------------------------------------ | | tracks | 7 | Track library management (CRUD, search, iteration) | | playlists | 9 | Playlist operations (create, manage tracks, smart playlists) | | tags | 4 | Tag management and assignment | | tagCategories | 3 | Tag category organization with colors | | control.player | 49 | Complete music player control and state | | control.* | 79 | DJ interface control (navigation, appearance, analysis) |

Total: 151+ methods providing comprehensive Lexicon DJ integration.

🔗 Related Projects

📄 License

MIT © Juan Pablo Prieto


🎧 Ready to build amazing DJ applications? Get started now