Lunacord

Quickstart

Wire Lunacord core with discord.js — Lavalink manager, gateway voice packets, and playback.

1. Install

bun add @lunacord/core discord.js

Optional: @lunacord/lyrics, @lunacord/cache-redis, @lunacord/plugins match what you need.

Download the latest Lavalink v4 jar and run:

java -jar Lavalink.jar

Default port is 2333, default password is youshallnotpass.

3. Create Lunacord and attach Discord

You forward gateway events, send op: 4 voice payloads through the shard, and bind identity after the client is ready:

import { Lunacord } from "@lunacord/core";
import { Client, GatewayIntentBits } from "discord.js";

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

const lunacord = Lunacord.create()
  .nodes([{ id: "main", host: "localhost", port: 2333, password: "youshallnotpass" }])
  .autoConnect(false)
  .resume(true)
  .sendGatewayPayload((guildId, payload) => {
    client.guilds.cache.get(guildId)?.shard.send(payload);
  })
  .build();

client.on("raw", (packet) => {
  lunacord.handleVoicePacket(packet);
});

client.once("clientReady", async () => {
  const user = client.user;
  if (!user) return;
  const numShards =
    client.shard?.count ?? (client.ws.shards ? client.ws.shards.size : undefined) ?? 1;
  lunacord.bindIdentity({ userId: user.id, numShards });
  await lunacord.connect();
});

await client.login(process.env.DISCORD_TOKEN);

4. Join voice and play

Use your own command handler. The usual flow is: resolve the invoker’s voice channel id, then create or reuse a player, connect to that channel, then load tracks:

const player = await lunacord
  .createPlayer()
  .setGuild(guildId)
  .setVoiceChannel(voiceChannelId)
  .setTextChannel(textChannelId)
  .connect();

const result = await player.searchAndPlay(query, "ytsearch");

See Lunacord and Player for the full API.

5. Batteries-included shortcut

For automatic raw forwarding, bindIdentity, default slash commands, and embeds, use MusicKit and the MusicKit Quickstart instead.

On this page