Discolink
    Preparing search index...

    Discolink

    Discolink

    Icon by juicy_fish
    API Reference | Coverage

    NPM Version Codecov Coverage

    The goal of this library is to abstract away obvious steps involved in the process of acting as an intermediary between Lavalink and Discord to give developers a cleaner and intuitive interface to work with.

    It's the JS ecosystem, how can we not have 30 libs for the same thing. My friends were monkey-patching, applying hotfixes, despite their clients being open-source; and I wanted to do a project professionally while exploring more of GitHub. This project follows SemVer and an Agile SDLC.

    • Runtime - one of the following:
    • Library - any gateway client that supports:
      • sending raw payloads over the connection
      • receiving raw payloads from the connection
    Basic Setup - JavaScript (ESM)
    import { Client } from "main-lib";
    import { Player } from "discolink";

    const client = new Client(...);

    const player = new Player({
    nodes: [], // add your nodes
    async forwardVoiceUpdate(guildId, payload) {
    // send the given payload to your gateway connection
    client.guilds.cache.get(guildId).shard.send(payload);
    }
    });

    client.on("raw", (payload) => {
    // call the handler on gateway dispatch
    player.voices.handleDispatch(payload);
    });

    client.login();
    Module Augmentation - TypeScript
    declare module "discolink" {
    interface QueueContext {
    textId: string;
    }

    interface CommonUserData {
    id: string;
    username: string;
    displayName: string;
    }

    interface CommonPluginInfo {
    save_uri?: string;
    }

    interface CommonPluginFilters {
    custom: string;
    }
    }
    Custom Plugin (with events) - TypeScript
    import { PlayerPlugin, type Player } from "discolink";

    export class CustomPlugin extends PlayerPlugin<{
    event: [a: string, b: object];
    }> {
    readonly name = "custom"; // 'readonly' is mandatory
    #player!: Player; // optional, just for convenience

    init(player: Player) {
    this.#player = player;
    player.on("nodeDispatch", this.#onDispatch);
    }

    #onDispatch(this: Player, ...args: unknown[]) {
    // work with data
    // e.g. transform -> name event -> dispatch
    }
    }
    • Handle track end reasons other than cleanup and finished
    • Handle voice states carefully, e.g. reconnecting, changingNode, etc.
    • Handle queue destruction/relocation, e.g. guild/channel delete, node close/disconnect, etc.

    Resuming a node's session after your bot restarts requires careful planning, depending on scale. As such, the lib has no plans to provide built-in support for it. Disable both autoSync and relocateQueues for predictable behavior if you're implementing this feature.

    Name Since Owner
    Mesuic 18th Feb 2026 @knifecodez
    Fuego 19th Feb 2026 @painfuego
    Flame 28th Feb 2026 @aiosqlite.db

    Key aspects of this lib were inspired from the following projects: