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

staytube-music

v1.0.0

Published

A modern Discord music library for discord.js v14, powered by Lavalink (Kazagumo/Shoukaku) — stable playback, multi-source search, queues, filters, and a simple API.

Readme

StayTube_Music

A modern music library for discord.js v14, powered by Lavalink. StayTube_Music gives you a small, clean API for playing music from YouTube, Spotify, SoundCloud, Apple Music and more, with stable playback that stays smooth no matter how many servers you're in.

Under the hood it builds on two excellent open-source libraries — Kazagumo and Shoukaku — which handle the Lavalink connection. StayTube_Music wraps them in a simpler, friendlier interface. Full credit for the audio engine goes to their authors (see the NOTICE file).

Why Lavalink

Lavalink is a standalone audio server. Your bot sends it a search or a URL, and Lavalink streams the audio straight into the voice channel — the audio never passes through your bot process. That's why it stays fast and stable under load, and why it handles sources like YouTube far more reliably than in-process approaches.

Requirements

  • Node.js 18+
  • A running Lavalink v4 server (self-hosted, or a free public node)
  • discord.js v14

Install

npm install staytube-music discord.js kazagumo shoukaku

kazagumo and shoukaku are peer dependencies — you install them yourself, so there's never a version clash.

Quick start

const { Client, GatewayIntentBits } = require("discord.js");
const { StayTubeMusic } = require("staytube-music");

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

const music = new StayTubeMusic(client, {
  nodes: [
    { name: "main", url: "localhost:2333", auth: "youshallnotpass", secure: false },
  ],
  defaultSearchEngine: "ytmsearch",
});

// IMPORTANT: forward raw voice packets to the library
client.on("raw", (d) => music.kazagumo.shoukaku.connections.get(d.d?.guild_id)?.setStateUpdate?.(d));

client.on("messageCreate", async (message) => {
  if (message.author.bot || !message.inGuild()) return;

  if (message.content.startsWith("!play ")) {
    const query = message.content.slice(6);
    const vc = message.member.voice.channel;
    if (!vc) return message.reply("Join a voice channel first.");

    const { result } = await music.play(vc, query, {
      member: message.member,
      textChannel: message.channel,
    });

    if (!result.tracks.length) return message.reply("No results found.");
    message.reply(`Added **${result.tracks[0].title}**`);
  }

  if (message.content === "!skip") {
    music.get(message.guildId)?.skip();
  }

  if (message.content === "!stop") {
    await music.stop(message.guildId);
  }
});

music.on("playerStart", (player, track) => {
  client.channels.cache.get(player.textId)?.send(`Now playing: **${track.title}**`);
});

client.login("YOUR_BOT_TOKEN");

Getting a Lavalink server

You have two options:

Free public node (quickest): grab a live node from one of these lists and drop its host/port/password into nodes:

  • https://lavainfo.netlify.app
  • https://lavalink.darrennathanael.com

Self-host (most reliable): download Lavalink from https://github.com/lavalink-devs/Lavalink, set a password in application.yml, and run it with Java 17+. Then use localhost:2333 with your password.

API

new StayTubeMusic(client, options)

| Option | Type | Default | Description | | --- | --- | --- | --- | | nodes | StayTubeNode[] | — (required) | Lavalink nodes: { name, url, auth, secure? } | | defaultSearchEngine | string | "ytmsearch" | Engine for plain-text searches | | plugins | KazagumoPlugin[] | [] | Extra source plugins (e.g. kazagumo-spotify) | | nodeOptions | object | {} | Advanced Shoukaku node options |

Methods

  • join(voiceChannel, textChannel, deaf?) → creates/returns a player for the guild.
  • search(query, requester?, engine?) → searches a URL or text; returns tracks.
  • play(voiceChannel, query, options) → join + search + queue + play in one call.
  • get(guildId) → the player for a guild, or undefined.
  • stop(guildId) → destroy the player and leave.

play options: { textChannel, member?, engine?, deaf? }.

Working with the player

The player returned is a Kazagumo player, so you get its full API:

const player = music.get(guildId);

player.pause(true);       // pause
player.pause(false);      // resume
player.skip();
player.setVolume(80);
player.seek(60000);       // ms
player.setLoop("track");  // "none" | "track" | "queue"
player.queue.add(track);
player.queue.shuffle();
console.log(player.queue.current, player.queue.length);

Events

Forwarded from the underlying engine:

music.on("playerStart",   (player, track) => {});
music.on("playerEnd",     (player, track) => {});
music.on("playerEmpty",   (player) => {});
music.on("playerException",(player, data) => {});
music.on("nodeReady",     (name) => {});
music.on("nodeError",     (name, error) => {});
music.on("nodeDisconnect",(name, count) => {});

Search engines

Depending on the plugins installed on your Lavalink node: ytsearch (YouTube), ytmsearch (YouTube Music), scsearch (SoundCloud), spsearch (Spotify), amsearch (Apple Music), dzsearch (Deezer), jssearch (JioSaavn).

Credits

The audio engine is provided by Kazagumo, Shoukaku, and Lavalink, all MIT-licensed and authored by their respective teams. StayTube_Music is a wrapper and does not claim ownership of them. See NOTICE.

License

MIT © StayTube_Music