Quick start
This is the smallest production-shaped setup. sendToShard is the only Discord-library-specific part, so the client works with discord.js, Oceanic, Eris, or a custom gateway wrapper.
1. Install
Section titled “1. Install”npm install nerox-llclientYou also need a running Lavalink v4 server and a Discord bot with the GuildVoiceStates intent.
2. Create the manager
Section titled “2. Create the manager”import { LavalinkManager } from "nerox-llclient";
const lavalink = new LavalinkManager({ nodes: [ { id: "primary", host: process.env.LAVALINK_HOST ?? "localhost", port: Number(process.env.LAVALINK_PORT ?? 2333), authorization: process.env.LAVALINK_PASSWORD ?? "youshallnotpass", secure: false, regions: ["asia", "us"], priority: 10, }, ], nodeSelection: { strategy: "health", }, sendToShard: (guildId, payload) => { // Forward the voice state/server payload to the Discord shard discordClient.ws.send(guildId, payload); }, client: { id: process.env.CLIENT_ID!, username: "my-music-bot", }, playerOptions: { onDisconnect: { autoReconnect: true, destroyPlayer: false }, onEmptyQueue: { destroyAfterMs: 30_000 }, },});For most bots, "players" is the best default. Use "health" for mixed hardware, "priority" for primary/backup nodes, or "custom" for an application-specific policy.
3. Connect and forward voice events
Section titled “3. Connect and forward voice events”discordClient.on("raw", (packet) => void lavalink.sendRawData(packet));discordClient.once("ready", async () => { await lavalink.init({ id: discordClient.user.id, username: discordClient.user.username, });});4. Search, queue, and play
Section titled “4. Search, queue, and play”const player = lavalink.createPlayer({ guildId, voiceChannelId, textChannelId, selfDeaf: true,});
await player.connect();
const result = await player.search({ query: "Daft Punk Get Lucky" }, requester, true);await player.queue.add(result.tracks.slice(0, 10));await player.play();The queue is persisted through the configured queue store. Useful helpers include player.queue.size, player.queue.isEmpty, player.queue.duration, player.queue.filterTracks(...), player.queue.shuffle(), and player.skip().
5. Listen to lifecycle events
Section titled “5. Listen to lifecycle events”lavalink.on("trackStart", (player, track) => { console.log(`${player.guildId}: ${track?.info.title}`);});
lavalink.on("queueEnd", (player) => { console.log(`Queue finished in ${player.guildId}`);});
lavalink.on("debug", (key, data) => { if (data.state === "error") console.error(key, data.error);});Selecting nodes explicitly
Section titled “Selecting nodes explicitly”const node = lavalink.getBestNode({ region: "asia", strategy: "priority",});
const player = lavalink.createPlayer({ guildId, voiceChannelId, node });If no node in the requested region is connected, the selector safely falls back to another connected node. See the API reference for NodeSelectionOptions and custom selectors.