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 🙏

© 2025 – Pkg Stats / Ryan Hefner

harmonylink

v2.0.0

Published

Seamlessly connect to Lavalink, NodeLink, and FrequenC nodes for high-quality audio streaming in your Discord bots. Supports Discord.js, Eris, Oceanic.js, and a powerful plugin system.

Readme

TypeScript

Contributors Forks Stargazers Issues MIT License

[!NOTE] HarmonyLink v2.0+ introduces advanced type safety with Result types, generic filter builders and a better plugin system cause the old one was not good enough ig. See Migration Guide for upgrading from older versions.

[!WARNING]
Support for Lavalink Version 3 is planned, but not confirmed to be done.

Features

  • Multi-library support: Discord.js v14, Eris, Oceanic.js
  • Plugin system: Extensible with lifecycle management
  • Type safety: Full TypeScript support, neverthrow Result types
  • Advanced filters: Type-safe audio filter builder
  • Robust node/player management
  • Modern, well-documented API

Demo

| URL | Features | Additional Information | |-----|----------|------------------------| | RhythmCore | Advanced Music bot With AI | Invite | | Example Bot | Verry basic example bot | coming soon |

Installation

npm install harmonylink

Quick Start (Discord.js v14)

import { DJSLibrary, HarmonyLink } from "harmonylink";
import { Client, GatewayIntentBits } from "discord.js";

const client = new Client({ 
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates] 
});

const music = new HarmonyLink({
  nodes: [{
    name: "Example Node",
    host: "localhost",
    port: 2333,
    password: "youshallnotpass",
    secure: false
  }],
  library: new DJSLibrary(client),
});

client.on("ready", async () => {
  // Create a player - using unwrapOr for cleaner code
  const player = (await music.createPlayer({
    guildId: "YOUR_GUILD_ID",
    voiceId: "VOICE_CHANNEL_ID",
    textId: "TEXT_CHANNEL_ID"
  })).unwrapOr(null);

  if (player) {
    // Search and play a track
    const response = (await music.resolve({ 
      query: "Rick Astley - Never Gonna Give You Up", 
      requester: client.user 
    })).unwrapOr(null);
    
    if (response && response.tracks.length > 0) {
      player.queue.add(response.tracks[0]);
      await player.play();
      console.log("Now playing!");
    }
  }
});

client.login("YOUR_BOT_TOKEN");

Result Types: HarmonyLink uses neverthrow Result types instead of throwing errors. You can handle them in three ways:

// Option 1: Check with .isOk() (explicit)
if (result.isOk()) {
  console.log(result.value); // Safe access
} else {
  console.error(result.error); // Handle error
}

// Option 2: Use .unwrapOr() (cleaner)
const value = result.unwrapOr(null); // Returns null if error
if (value) {
  console.log(value); // Use the value
}

// Option 3: Use .match() (pattern matching)
result.match(
  (value) => console.log(value),
  (error) => console.error(error)
);

// So it would look something like this:
const tracks = await <Player>.resolve({ query: "Rick Astley - Never Gonna Give You Up", requester: client.user })

tracks.match(
    (tracks) => <Player>.queue.add(tracks[0]),
    (error) => console.error("Failed to resolve track:", error.message)
);

For more examples, please refer to the Documentation

Documentation

Plugins

HarmonyLink supports plugins for custom features and integrations. See the Plugin Guide and loadPlugins for details.

Migration Guide

From v1.x to v2.x

Breaking Changes:

  1. Result Types: All async methods now return Result<T, E> instead of throwing errors

    // v1.x (old)
    try {
      const player = await music.createPlayer(options);
    } catch (error) {
      console.error(error);
    }
       
    // v2.x (new)
    const playerResult = await music.createPlayer(options);
    if (playerResult.isOk()) {
      const player = playerResult.value;
    } else {
      console.error(playerResult.error);
    }
       
    // Or use unwrapOr for cleaner code
    const player = (await music.createPlayer(options)).unwrapOr(null);
  2. Plugin System: New lifecycle-based plugin architecture

    // v1.x (old)
    class MyPlugin extends Plugin {
      load() { /* ... */ }
    }
       
    // v2.x (new)
    class MyPlugin extends AbstractPlugin {
      async initialize(manager: HarmonyLink): Promise<Result<void, Error>> {
        // Plugin initialization logic
        return ok();
      }
    }
  3. Import Changes: Package exports have been reorganized

    // v1.x (old)
    import { HarmonyLink } from "harmonylink/dist/HarmonyLink";
       
    // v2.x (new)
    import { HarmonyLink } from "harmonylink";

New Features in v2.x:

  • Type-safe filters: Enhanced audio filter system with better TypeScript support
  • Improved error handling: Comprehensive Result types throughout the API
  • Better plugin lifecycle: More robust plugin loading and management

For detailed migration assistance, see the full documentation.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.