Medusa/developer documentation/Leaderboard Providers

Leaderboard Providers

Register custom leaderboards, ranking algorithms, and unit formatters.

Modules can declare custom leaderboard providers that automatically integrate with Discord's /leaderboard slash command and the web dashboard's Leaderboards view.

Leaderboard providers reside in resources/leaderboards/ and load from every *.js file located directly in that directory.

Base Class Definition

modules/example/resources/leaderboards/activity.js
import { Leaderboards } from "#medusa/modules";

export class ActivityLeaderboard extends Leaderboards {
    constructor(medusa) {
        super(medusa, {
            name: "activity_score",
            label: "Activity Score",
            group: "Community",
            format: "number",
            emoji: "⭐",
            unit: "Points",
            singular: "Point",
            order: 1
        });
    }

    async list(guild) {
        const model = this.medusa.modules.models.get(this.module, "user_scores");
        if (!model) return [];

        const records = await model.list({ guildId: guild.id });
        return records
            .sort((a, b) => b.score - a.score)
            .slice(0, 100)
            .map(record => ({
                userId: String(record.userId),
                value: record.score,
                sub: `Level ${record.level} • Streak: ${record.streak} days`,
                stats: [
                    { label: "Level", value: record.level },
                    { label: "Streak", value: `${record.streak}d` }
                ]
            }));
    }
}

Constructor Options

The configuration object passed to super(medusa, meta) accepts the following properties:

PropertyTypeDefaultDescription
namestringRequiredUnique leaderboard identifier.
labelstringnameDisplay title shown in menus, embeds, and dashboard tables.
groupstring"General"Categorization group used to organize multiple leaderboards.
formatstring"number"Value formatting style: "number", "currency", or "duration".
typestring"card"Default presentation mode: "card" or "embed".
emojistring""Emoji prefix displayed next to values.
unitstring""Plural unit name appended to values (e.g. "Credits", "Messages").
singularstringunitSingular unit name used when value is 1 (e.g. "Credit", "Message").
ordernumber0Sort priority among leaderboards within the same group.

Supported Formatting Modes

The format property determines how Medusa renders values in Discord embeds and dashboard widgets:

Format ModeSample OutputFormatting Rules
"number"1,250 PointsLocalized integer formatting with unit suffix.
"currency"$ 5,000 CoinsPrepends emoji or currency symbol and appends unit label.
"duration"4h 12mConverts numeric seconds into human-readable hours and minutes.

The list(guild) Method

Every provider must implement async list(guild) which receives the active Discord.js Guild instance and returns an array of ranked participant objects.

Return Item Schema

PropertyTypeRequiredDescription
userIdstringYesDiscord snowflake ID of the member. Used to resolve usernames and avatars.
valuenumberYesRaw numeric value used for ranking calculations and sorting.
displaystringNoOptional pre-formatted text override replacing automatic numeric formatting.
substringNoSubtitle text displayed below the user's name in list items.
statsArray<object>NoArray of supplementary metric objects containing label and value (string or number) rendered as badges.

Leaderboard Manager Methods

The root this.medusa.leaderboards service provides methods used across Discord commands and web views:

const allTypes = this.medusa.leaderboards.types();

const rows = await this.medusa.leaderboards.list("activity_score", guild);

const page = this.medusa.leaderboards.paginate(rows, 0, 10);

const position = this.medusa.leaderboards.position(rows, interaction.user.id);

Leaderboard Presentation Types

Medusa supports two presentation formats for leaderboards in Discord:

  • Card ("card"): Renders a 1024x750 canvas graphic with rank indicators, compact scores, server branding, and member position.
  • Embed ("embed"): Sends a standard Discord embed with medal emojis and mentionable member strings.

The /leaderboard slash command includes an optional format option with choices Card and Embed. When omitted, the command defaults to the server's configured presentation mode (defaultType in Core leaderboard configuration), falling back to the provider's descriptor type or "card".

Server administrators can configure the default presentation type directly from the top bar of the Leaderboard page in the web dashboard or under Configs > Core > Leaderboard.