Package Exports
- megs-discord-progress
- megs-discord-progress/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (megs-discord-progress) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
megs-discord-progress
Beautiful live-updating progress bars for Discord bots — music players, downloads, batch tasks. Supports embed and ANSI colored code block styles.
Most Discord music bots just show text like "Now playing: X". This package renders smooth, sub-character precision progress bars with ANSI colors, automatic rate-limit-safe message editing, and both embed and code-block styles. Made to pair with megs-ascii-progress.
Built by megs · megsnaf
Features
- Music bar — Now-playing with live-updating progress, play/pause/seek support
- Task bar — Generic progress bar for downloads, imports, batch jobs
- Two styles — Discord embed card OR ANSI code block (both supported, your choice)
- ANSI colored bars — Uses Discord's
ansicode block syntax for real colors - Sub-character smoothness — 8× finer resolution with
▏▎▍▌▋▊▉█ - Rate-limit safe — 2.5s minimum update interval enforced
- Auto-cleanup — Handles deleted messages, channel errors gracefully
- TypeScript-first with full type definitions
- Zero friction —
peerDependencieson discord.js, no extra installs
Install
npm install megs-discord-progressRequires discord.js@^14 in your project.
Quick Start — Music Bar
const { MegsMusicBar } = require('megs-discord-progress');
const bar = new MegsMusicBar({
channel: message.channel,
song: {
title: 'Kuzu Kuzu',
author: 'Tarkan',
duration: 222000,
url: 'https://youtube.com/...',
thumbnail: 'https://...',
requestedBy: message.author.tag,
},
style: 'embed',
updateInterval: 5000,
color: 'green',
emptyColor: 'gray',
width: 20,
});
await bar.start();
player.on('pause', () => bar.pause());
player.on('resume', () => bar.resume());
player.on('end', () => bar.stop());Renders as a Discord embed that updates every 5 seconds with a live progress bar, time stamps, thumbnail, and author info.
Quick Start — Task Bar
const { MegsTaskBar } = require('megs-discord-progress');
const bar = new MegsTaskBar({
channel: message.channel,
total: 1000,
label: 'Importing users',
style: 'embed',
showFraction: true,
showEta: true,
showSpeed: true,
color: 'cyan',
});
await bar.start();
for (const user of users) {
await importUser(user);
bar.increment();
}
await bar.stop('Import complete!');Styles
style: 'embed' (default)
Rich Discord embed with title, description, thumbnail, and fields. Best for user-facing commands like !play.
style: 'code'
ANSI colored code block. Best for admin/debug commands or when you want a compact look. Uses Discord's ansi code block syntax for real color rendering.
API — MegsMusicBar
new MegsMusicBar(options: MegsMusicBarOptions)Options
| Option | Type | Default | Description |
|---|---|---|---|
channel |
TextBasedChannel |
required | Channel to send message in |
song |
MegsSong |
required | Song info |
style |
'embed' | 'code' |
'embed' |
Rendering style |
updateInterval |
number |
5000 |
Edit interval in ms (min 2500) |
showTimestamps |
boolean |
true |
Show 1:24 / 3:42 |
width |
number |
20 |
Bar width in characters |
filledChar |
string |
█ |
Character for filled portion |
emptyChar |
string |
░ |
Character for empty portion |
color |
MegsAnsiColor |
— | Filled color (code style only) |
emptyColor |
MegsAnsiColor |
'gray' |
Empty color (code style only) |
embedColor |
number |
0x5865f2 |
Embed color (embed style only) |
title |
string |
'🎵 Now Playing' |
Embed title |
footer |
string |
— | Embed footer |
getCurrentPosition |
() => number |
— | Custom position getter (integrate with player) |
onStop |
() => void |
— | Called when bar stops |
MegsSong
{
title: string;
url?: string;
duration: number; // in milliseconds
thumbnail?: string;
author?: string;
requestedBy?: string;
}Methods
await bar.start() // Send the initial message
bar.pause() // Pause (icon becomes ⏸️)
bar.resume() // Resume playback
bar.seek(positionMs: number) // Jump to a position
bar.updateSong(song: MegsSong) // Switch to next song (for queues)
await bar.stop() // Finalize the message (shows ⏹️)
await bar.destroy() // Delete the message entirely
bar.getPosition(): number // Current position in ms
bar.getState(): 'playing' | 'paused' | 'stopped'
bar.getMessage(): Message | nullAPI — MegsTaskBar
new MegsTaskBar(options: MegsTaskBarOptions)Options
| Option | Type | Default | Description |
|---|---|---|---|
channel |
TextBasedChannel |
required | Channel to send message in |
total |
number |
required | Max value |
label |
string |
'Processing' |
Task label |
style |
'embed' | 'code' |
'embed' |
Rendering style |
updateInterval |
number |
3000 |
Edit interval in ms (min 2500) |
showPercent |
boolean |
true |
Show 45% |
showFraction |
boolean |
false |
Show 450/1000 |
showEta |
boolean |
true |
Show ETA: 00:42 |
showSpeed |
boolean |
false |
Show 1.2 MB/s or 24/s |
width |
number |
20 |
Bar width |
color |
MegsAnsiColor |
— | Filled color (code style) |
embedColor |
number |
0x5865f2 |
Embed color |
title |
string |
'⚙️ Task in progress' |
Embed title |
description |
string |
— | Embed description |
onComplete |
() => void |
— | Called on completion |
Methods
await bar.start(initialValue?)
bar.update(value: number)
bar.increment(amount?: number)
bar.setLabel(label: string)
bar.setTotal(total: number)
bar.bytesMode(enabled?: boolean) // Format as bytes (1.2MB)
await bar.stop(finalMessage?)
await bar.destroy()
bar.getPercent(): number
bar.getMessage(): Message | nullANSI Colors (for style: 'code')
Discord's ansi code block supports these colors: gray, red, green, yellow, blue, pink, cyan, white.
{ style: 'code', color: 'green', emptyColor: 'gray' }Rate Limit Safety
Discord rate-limits message edits to roughly 5 per 5 seconds per channel. This package enforces a minimum updateInterval of 2500ms to stay well under that limit. Don't try to override it — you'll just get 429s.
Integration Examples
With discord-player
const { useMainPlayer } = require('discord-player');
player.events.on('playerStart', (queue, track) => {
const bar = new MegsMusicBar({
channel: queue.metadata.channel,
song: {
title: track.title,
author: track.author,
duration: track.durationMS,
thumbnail: track.thumbnail,
requestedBy: track.requestedBy?.tag,
},
getCurrentPosition: () => queue.node.getTimestamp().current.value,
});
await bar.start();
queue.metadata.bar = bar;
});
player.events.on('playerPause', (queue) => queue.metadata.bar?.pause());
player.events.on('playerResume', (queue) => queue.metadata.bar?.resume());
player.events.on('emptyQueue', (queue) => queue.metadata.bar?.stop());With @discordjs/voice
const { createAudioPlayer, AudioPlayerStatus } = require('@discordjs/voice');
const player = createAudioPlayer();
const bar = new MegsMusicBar({ /* ... */ });
player.on(AudioPlayerStatus.Playing, () => bar.resume());
player.on(AudioPlayerStatus.Paused, () => bar.pause());
player.on(AudioPlayerStatus.Idle, () => bar.stop());
await bar.start();HTTP download with progress
const axios = require('axios');
const fs = require('fs');
const { data, headers } = await axios.get(url, { responseType: 'stream' });
const total = parseInt(headers['content-length'], 10);
const bar = new MegsTaskBar({
channel: message.channel,
total,
label: 'Downloading',
showSpeed: true,
showEta: true,
}).bytesMode(true);
await bar.start();
let received = 0;
data.on('data', (chunk) => {
received += chunk.length;
bar.update(received);
});
data.on('end', () => bar.stop('Download complete!'));
data.pipe(fs.createWriteStream('output.zip'));Compatibility
- Node.js 16.11+
- discord.js v14+ (peerDependency — install in your project)
License
MIT © megs
Companion Package
megs-ascii-progress— Terminal progress bars with the same sub-character smoothness