{"id":18879341,"url":"https://github.com/azusfin/lavacoffee","last_synced_at":"2026-03-02T22:48:14.864Z","repository":{"id":44898641,"uuid":"422416374","full_name":"Azusfin/lavacoffee","owner":"Azusfin","description":"A fast and rich-featured lavalink wrapper for node.js","archived":false,"fork":false,"pushed_at":"2022-01-19T22:50:24.000Z","size":1809,"stargazers_count":7,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-22T13:41:55.514Z","etag":null,"topics":["discord-js","discord-music-bot","discordjs","eris","lavalink","lavalink-client","lavalink-music","lavalink-wrapper"],"latest_commit_sha":null,"homepage":"https://Azusfin.github.io/lavacoffee/index.html","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Azusfin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-10-29T02:21:40.000Z","updated_at":"2024-06-07T20:04:12.000Z","dependencies_parsed_at":"2022-09-03T05:00:42.445Z","dependency_job_id":null,"html_url":"https://github.com/Azusfin/lavacoffee","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/Azusfin/lavacoffee","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azusfin%2Flavacoffee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azusfin%2Flavacoffee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azusfin%2Flavacoffee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azusfin%2Flavacoffee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Azusfin","download_url":"https://codeload.github.com/Azusfin/lavacoffee/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azusfin%2Flavacoffee/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267552097,"owners_count":24106000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discord-js","discord-music-bot","discordjs","eris","lavalink","lavalink-client","lavalink-music","lavalink-wrapper"],"created_at":"2024-11-08T06:35:29.816Z","updated_at":"2026-03-02T22:48:14.803Z","avatar_url":"https://github.com/Azusfin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lavacoffee\n\u003e A fast and rich-featured lavalink wrapper for node.js\n\n[![NPM Version](https://img.shields.io/npm/v/lavacoffee.svg?maxAge=3600)](https://www.npmjs.com/package/lavacoffee)\n[![NPM Downloads](https://img.shields.io/npm/dt/lavacoffee.svg?maxAge=3600)](https://www.npmjs.com/package/lavacoffee)\n\n# Table Of Contents\n- [Features](#features)\n- [Installation](#installation)\n- [Documentation](#documentation)\n- [Getting Lavalink](#getting-lavalink)\n- [Cycle](#cycle)\n- [Test](#test)\n- [Examples](#examples)\n  - [Init](#init)\n  - [Nodes](#nodes)\n  - [Voice Updates](#voice-updates)\n  - [Events](#events)\n  - [Resuming Session](#resuming-session)\n  - [RoutePlanners](#routeplanners)\n  - [Lavalink Plugins](#lavalink-plugins)\n  - [Track Decoding](#track-decoding)\n  - [Players](#players)\n    - [Creating](#creating)\n    - [Getting](#getting)\n    - [Replaying](#replaying)\n    - [Filters](#filters)\n    - [Unknown Track](#unknown-track)\n\n# Features\n- Easy-to-use\n- Performant\n\n# Installation\n\u003e NPM (Stable) =\u003e npm install lavacoffee\n\n\u003e Github (Dev) =\u003e npm install Azusfin/lavacoffee#main\n\n# Documentation\n\u003e https://azusfin.github.io/lavacoffee\n\n# Getting Lavalink\nDownload the latest binaries from the [CI Server (Dev)](https://ci.fredboat.com/repository/download/Lavalink_Build?guest=1\u0026branch=refs/heads/dev)\n\nPut an [application.yml](https://github.com/freyacodes/Lavalink/blob/master/LavalinkServer/application.yml.example) in your working directory.\n\nRun with `java -jar Lavalink.jar`\n\nDocker images are available on the [Docker hub](https://hub.docker.com/r/fredboat/lavalink/)\n\n# Cycle\n\u003e Init lava client\n\n\u003e Add some nodes\n\n\u003e Play track\n\n\u003e Grab some coffee ☕\n\n# Test\n[Test Bot](https://github.com/Azusfin/lavacoffee/blob/main/test/index.ts)\n\u003e npm run test\n\n# Examples\n### Init\n```ts\n// Importing lava instance constructor\nimport { CoffeeLava } from \"lavacoffee\"\n\n// Construct the lava instance\nconst lava = new CoffeeLava(lavaOptions)\n\n// Init the lava instance\nlava.init(clientID)\n```\n\n### Nodes\n```ts\n// Adding a node\nlava.add(nodeOptions)\n\n// More nodes\nlava.add(nodeOptions1)\nlava.add(nodeOptions2)\n...\n```\n\n### Voice Updates\n```ts\n// Payload can be a voice state update payload or a voice server update payload\nlava.updateVoiceData(payload)\n```\n\n### Events\nhttps://azusfin.github.io/lavacoffee/interfaces/LavaEvents.html\n```ts\nlava.on(eventName, (...args) =\u003e { ... })\n```\n\n### Resuming Session\n```ts\n/**\n * Lavalink got a feature\n * which will allow for resuming\n * a session after it got\n * disconnected\n */\n\n/**\n * After v1.2.0, lavacoffee\n * added support for this feature,\n * allowing for resuming lavalink session\n * incase of bot restarted\n */\n\n// Create the resume configuration\nconst config = {\n  // The resume custom key for resuming lavalink session\n  key: \"somekey\",\n  // The timeout for the session, if timeout is passed before resumed, it can't be resumed anymore\n  timeout: 60, // 60 seconds\n  // Incase of player resumed, it must be handled manually by the user\n  handle(lava, guildID, callback) {\n    // Creating the player\n    const player = lava.create({ guildID })\n\n    // Redo the player state, e.g getting the player queue from database\n    ...\n\n    // Call callback to indicate as done\n    callback(player)\n  }\n}\n\n// Creating lava instance\nconst lava = new CoffeeLava({\n  resumeConfig: config,\n  /** other lava options */\n})\n...\n```\n\n### RoutePlanners\nhttps://github.com/freyacodes/Lavalink/blob/master/IMPLEMENTATION.md#routeplanner-api\n```ts\n// RoutePlanner instance is available within Node instance\nconst node = lava.nodes.get(nodeName)\nconst { routePlanner } = node\n\n// Get routePlanner status\n// If no routePlanner is set on node-side, it will return undefined\nawait routePlanner.status()\n\n// Unmark a failed address\n// Return true if success, otherwise false\nawait routePlanner.freeAddress(address)\n\n// Unmark all failed address\n// Return true if success, otherwise false\nawait routePlanner.freeAllAddress()\n```\n\n### Lavalink Plugins\nPlugins are managed in the lavalink server itself.\n\nbut you can make managing plugins in the node more spicier and stricter in lavacoffee\n```ts\n/**\n * Using required plugins option\n * on the lava instance make sure\n * all nodes have the plugins\n * otherwise they will be ignored\n */\n\n// Incase if one of your worker messed up the plugins on the server...\n\n// Example when creating the instance\nconst lava = new CoffeeLava({\n  requiredPlugins: [\"Spotify-Plugin\"],\n  send: (guildID, payload) =\u003e { ... }\n})\n\n/**\n * Using required plugins option\n * on search query make sure the searching\n * doesn't use node that doesn't have\n * the plugins\n */\n\n// Example\nconst searchResult = await lava.search({\n  query: url,\n  requiredPlugins: [\"Spotify-Plugin\"]\n}, author)\n\n/**\n * Using required plugins option\n * on player make sure the player\n * doesn't use node that doesn't have\n * the plugins\n */\n\n// Example\nconst player = lava.create({\n  guildID: guild.id,\n  requiredPlugins: [\"Spotify-Plugin\"]\n})\n```\n\n### Track Decoding\nDecoding and encoding tracks are also available locally\n\n```ts\n// Import decoder and encoder from utils\nimport { Utils } from \"lavacoffee\"\nconst { TrackUtils } = Utils\n\n// Decode track\nconst track = TrackUtils.decodeTrack(rawTrack)\n\n// Encode it back\nTrackUtils.encodeTrack(track)\n```\n\nWith more details:\n```ts\n// Decode spotify track from spotify-plugin\nconst spotifyTrack = TrackUtils.decodeTrack\u003c{\n  isrc?: string,\n  artworkUrl?: string\n}\u003e(\n  rawSpotifyTrack,\n  (_, data) =\u003e ({\n    isrc: data.readNullableText(),\n    artworkUrl: data.readNullableText()\n  })\n)\n\n// Encode it back\nTrackUtils.encodeTrack\u003c{\n  isrc?: string,\n  artworkUrl?: string\n}\u003e(\n  spotifyTrack,\n  (track, data) =\u003e {\n    data.writeNullableText(track.isrc)\n    data.writeNullableText(track.artworkUrl)\n  }\n)\n```\n\n## Players \n### Creating\n```ts\n// THis will create a new player or get an existing if exist\nconst player = lava.create(playerOptions)\n\n// Connect to voice channel\nplayer.options.voiceID = voiceChannelID\nplayer.connect()\n\n// Adding tracks\nplayer.queue.add(tracks)\n\n// Play\nplayer.play()\n...\n```\n\n### Getting\n```ts\n// Use this if you only want to get a player without creating it\nconst player = lava.get(guildID)\n\nif (!player) return\n\n// Getting queue\nconst queue = player.queue\n\n// Getting current track\nconst track = player.queue.current\n...\n```\n\n### Replaying\n```ts\n/**\n * When player is disconnected from node\n * it will automatically move to another node\n * then replay the track on current position\n * you can disable this behaviour by setting\n * the `autoReplay` option to false in LavaOptions\n */\n\n// Replay events\n\n// When successfully replayed\nlava.on(\"playerReplay\", player =\u003e { ... })\n\n// When there's an error while replaying\nlava.on(\"replayError\", (player, error) =\u003e { ... })\n...\n```\n\n### Filters\n```ts\n/**\n * LavaCoffee also supports lavalink filters\n * it also got filters builder to manage filters easier\n */\n\n// Importing filters builder\nimport { CoffeeFilters } from \"lavacoffee\"\n\n// Creating filters\nconst filters = new CoffeeFilters()\n\n// Example on setting equalizer\nfilters.equalizers\n  .setBand(2, 0.25)\n  .setBand(6, -0.25)\n\n// Example to enable karaoke filter\nfilters.karaoke.enabled = true\n\n// Example on setting 2x speed and half pitch\nfilters.timescale\n  .setSpeed(2)\n  .setPitch(0.5)\n\n// Example on setting vibrato filter\nfilters.vibrato\n  .setFrequency(2)\n  .setDepth(0.5)\n\n// Example on setting the audio to only left channel\nfilters.channelMix\n  .setRightToLeft(1)\n  .setRightToRight(0)\n\n// Set the filters\nplayer.setFilters(filters)\n```\n\n### Unknown Track\n```ts\n/**\n * You can make an unknown track\n * from unknown source, and resolve it\n * once it playing\n */\n\n// Importing unresolved track\nimport { UnresolvedTrack } from \"lavacoffee\"\n\n// Creating the track\nconst track = new UnresolvedTrack(title, author, duration, requester)\n\n// Adding the track\nplayer.queue.add(track)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazusfin%2Flavacoffee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazusfin%2Flavacoffee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazusfin%2Flavacoffee/lists"}