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

teralink

v0.2.0

Published

A next-generation, super-performant, v4-only Lavalink manager for Node.js with advanced features, smart search, enhanced error handling, performance monitoring, and optimized resource usage.

Readme


🚀 Teralink: Next-Generation Lavalink Manager

🎧 Modern, Fast, and Extensible Lavalink Client

Teralink is a next-generation, v4-only Lavalink manager for Discord bots, designed for performance, extensibility, and a beautiful developer experience. Enjoy seamless music streaming, advanced queueing, robust event handling, and real-time features—all in one open-source package.


🌟 Features

🔥 New in v0.2.0

  • 🧠 Smart Search: Automatic source detection from URLs and query enhancement for better results
  • 🛡️ Enhanced Error Handling: Intelligent retry logic with exponential backoff for network errors
  • 📊 Performance Monitoring: Real-time metrics tracking including cache hit rates and memory usage
  • 🧹 Automatic Memory Management: Intelligent cleanup and leak prevention with configurable thresholds
  • 📋 Advanced Queue Analytics: Comprehensive statistics, search functionality, and duplicate detection
  • ⚡ Enhanced Caching: 2.5x larger cache with longer TTL for improved performance

🎵 Core Features

  • Super-performant node management and failover (automatic player migration if a node goes offline)
  • Advanced player controls and queueing with real-time analytics
  • Multi-source search (YouTube, Spotify, SoundCloud, Apple Music, and more)
  • TypeScript support and comprehensive documentation
  • Plugin system for extensibility
  • Real-time voice channel status sync (statusSync)
  • Region-aware node selection and health diagnostics
  • Auto-resume, advanced queue, lyrics (including real-time LRC), and more
  • Clean, nested config structure for easier setup
  • Intelligent caching for super-fast track/playlist resolution
  • Automatic player migration (failover): If a Lavalink node goes offline and dynamicSwitching is enabled, Teralink will automatically move all affected players to a healthy node and resume playback from the last position.

💡 Why Choose Teralink?

  • Built for modern Discord bots (Lavalink v4+ only)
  • No legacy code, fully open source
  • Inspired by the best, but uniquely original
  • Designed for both beginners and advanced devs
  • Created and maintained by Ryuzii

📦 Installation

npm install teralink

🚀 Quick Start

const { Teralink } = require('teralink');
const { Client, GatewayIntentBits } = require('discord.js');

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

const nodes = [
  { name: 'Lavalink', host: 'localhost', port: 2333, password: 'youshallnotpass', secure: false }
];

function send(packet) {
  const guildId = packet.d?.guild_id || packet.guild_id;
  if (!guildId) return;
  const guild = client.guilds.cache.get(guildId);
  if (guild && guild.shard) {
    guild.shard.send(packet);
  } else if (client.ws && typeof client.ws.send === 'function') {
    client.ws.send(packet);
  }
}

const tera = new Teralink(client, LAVALINK_NODES, {
  send,
  source: { default: 'ytmsearch' },
  rest: {
    version: 'v4',
    retryCount: 3,
    timeout: 5000
  },
  plugins: [],
  sync: { template: 'Now playing: {title} by {author}' },
  resume: {
    key: 'teralink-resume',
    timeout: 60000
  },
  node: {
    dynamicSwitching: true,
    autoReconnect: true,
    ws: {
      reconnectTries: 5,
      reconnectInterval: 5000
    }
  },
  autopauseOnEmpty: true,
  lazyLoad: {
    enabled: true,
    timeout: 5000
  }
});

client.once('ready', () => {
  tera.init(client.user.id);
  console.log(`Logged in as ${client.user.tag}`);
});

// See exampleBot.js for full command and event handling

🛠️ Advanced Usage

🖧 Node Management

tera.createNode({ name: 'Backup', host: 'localhost', port: 2444, password: 'backup', secure: false });
tera.destroyNode('Backup');
console.log(tera.getNodesHealth());
console.log(tera.getBestNodeForRegion('us'));

🎚️ Player Controls

player.pause();
player.play();
player.seek(60000); // Seek to 1 minute
player.setVolume(80);
player.filters.setBassboost(true);
player.setLoop('track');
player.queue.shuffle();

📚 Queue Controls

player.queue.move(0, 3); // Move first track to position 3
player.queue.remove(2); // Remove track at index 2
console.log(player.queue.toArray());

🧠 Smart Search (New in v0.2.0)

// Smart search with automatic source detection and query enhancement
const results = await tera.smartSearch('https://open.spotify.com/track/xyz', user);
const enhanced = await tera.smartSearch('lofi hip hop official music video', user, {
  limit: 5,
  smartSearch: true
});

// Batch search for multiple queries
const queries = ['song1', 'song2', 'song3'];
const batchResults = await tera.batchSearch(queries, user, { limit: 10 });

// Traditional search still available
const yt = await tera.search('ytsearch:lofi hip hop', user);
const sc = await tera.search('scsearch:chill beats', user);

📊 Performance Monitoring (New in v0.2.0)

// Get comprehensive performance metrics
const metrics = tera.getPerformanceMetrics();
console.log('Cache Hit Rate:', metrics.cacheHitRate + '%');
console.log('Memory Usage:', metrics.memoryUsage.heapUsagePercentage + '%');

// Memory management
const memory = tera.getMemoryUsage();
tera.performMemoryCleanup(); // Manual cleanup
tera.resetPerformanceMetrics();

📋 Advanced Queue Analytics (New in v0.2.0)

// Comprehensive queue statistics
const stats = player.queue.getStats();
console.log('Total tracks:', stats.totalTracks);
console.log('Estimated playtime:', stats.estimatedPlaytime);
console.log('Unique artists:', stats.uniqueArtists);

// Advanced search within queue
const searchResults = player.queue.searchAdvanced('lofi', {
  limit: 5,
  fuzzy: true
});

// Queue optimization
const removedCount = player.queue.removeDuplicates('uri');
await player.queue.shuffleAsync();

📢 Events

tera.on('trackStart', (player, track) => { /* ... */ });
tera.on('queueEnd', player => { /* ... */ });
tera.on('playerError', (player, error) => { /* ... */ });
tera.on('debug', message => { console.log(message); });

🧩 Extending Teralink

You can provide your own Player/Queue classes for custom behavior:

class MyPlayer extends Player {
  // Custom logic...
}

const tera = new Teralink(client, nodes, {
  send,
  customPlayerClass: MyPlayer
});

📝 TypeScript Support

  • Full types for all classes, options, and events
  • Enhanced TypeScript definitions for v0.2.0 features
  • See build/index.d.ts for details and autocompletion

📖 Documentation


🤖 Example Bot

See test/exampleBot.js for a real-world Discord.js bot using Teralink, including play, queue, skip, stop, nowplaying, and real-time lyrics commands, and demonstrating the new clean, nested config style.


🤝 Contributing

Contributions, issues, and feature requests are welcome!

  • Fork the repo and submit a pull request
  • Open an issue for bugs or suggestions

💬 Support

Need help? Join our Discord server or open an issue!


📄 License

MIT


🙏 Thanks & Acknowledgements

Thank you for choosing Teralink!

Special thanks:

  • The Euralink project and contributors for inspiration
  • The Discord music bot community
  • Everyone who tests, reports bugs, or contributes ideas