Getting Started

Configuration

Configuration Reference

The config.yaml file controls all aspects of your leaderboard system.

Configuration Schema

Organization (org)

Basic information about your organization.

org:
  name: string # required - Organization name
  description: string # required - Short description
  url: string (URL) # required - Organization website
  logo_url: string (URL) # required - Logo image URL (can use /assets/* for local assets)
  start_date: string (date) # optional - Organization founding date
  socials: # optional - Social media links
    github: string (URL)
    slack: string (URL)
    linkedin: string (URL)
    youtube: string (URL)
    email: string (email)

Example:

org:
  name: Open Healthcare Network
  description: Building connected healthcare systems
  url: https://ohc.network
  logo_url: /assets/logo.svg  # Local asset from data/assets/
  start_date: 2020-03-08
  socials:
    github: https://github.com/ohcnetwork
    slack: https://slack.ohc.network

Meta (meta)

SEO and site metadata.

meta:
  title: string # required - Site title
  description: string # required - Site description
  image_url: string (URL) # required - OpenGraph image (can use /assets/* for local assets)
  site_url: string (URL) # required - Canonical site URL
  favicon_url: string (URL) # required - Favicon URL (can use /assets/* for local assets)

Example:

meta:
  title: OHC Contributors
  description: Track contributions across OHC projects
  image_url: /assets/og-image.png  # Local asset from data/assets/
  site_url: https://contributors.ohc.network
  favicon_url: /assets/favicon.ico  # Local asset from data/assets/

Leaderboard (leaderboard)

Leaderboard-specific configuration.

leaderboard:
  data_source: string # optional - Data source URL
  theme: string (URL) # optional - Custom theme CSS URL
  roles: # required - Role definitions
    [role_id]:
      name: string # required - Display name
      description: string # optional - Role description
      hidden: boolean # optional - Hide from leaderboard

  top_contributors: # optional - Activity slugs to highlight
    - string

  social_profiles: # optional - Social icon mappings
    [platform]:
      icon: string # Lucide icon name

  aggregates: # optional - Custom aggregates
    global: # Show on home page
      - string
    contributor: # Show on profile pages
      - string

  data_explorer: # optional - Data Explorer configuration
    enabled: boolean # optional - Enable/disable (default: true)
    source: string # optional - Database URL or path (default: "/data.db")

  plugins: # optional - Plugin configurations
    [plugin_id]:
      name: string # optional - Display name
      source: string (URL) # required - Plugin manifest URL
      config: # optional - Plugin-specific config
        [key]: any

  leaderboard: # optional - Leaderboard display settings
    all_contributors: # optional - All Contributors table options
      activity_definitions: # optional - Activity definition slugs to show as columns
        - string

Data Explorer (data_explorer)

The Data Explorer provides an in-browser SQL REPL powered by WebAssembly. It can be toggled on or off, and the database source can point to a local or external URL.

leaderboard:
  data_explorer:
    enabled: boolean # optional - Enable the Data Explorer (default: true)
    source: string # optional - URL or path to the database file (default: "/data.db")

Defaults: When the data_explorer key is omitted, the feature is enabled and uses /data.db (shipped as a static asset alongside the site).

Examples

Disable the Data Explorer entirely:

leaderboard:
  data_explorer:
    enabled: false

Host the database externally (e.g., on GitHub Pages to work around Cloudflare Pages' 25 MiB file size limit):

leaderboard:
  data_explorer:
    source: https://yourorg.github.io/leaderboard-data/data.db

When source is set to an external URL, the prebuild step skips copying the .db file into public/, keeping the deployed bundle small. The browser fetches the database directly from the external host using HTTP Range Requests.

See the Data Explorer documentation for detailed instructions on hosting the database on GitHub Pages.

Leaderboard Display (leaderboard.leaderboard)

Control what is shown in the leaderboard's "All Contributors" table.

Activity Definition Columns

By default, the All Contributors table does not show per-activity-type breakdown columns. To display specific activity types as individual columns, list their slugs:

leaderboard:
  leaderboard:
    all_contributors:
      activity_definitions:
        - pr_merged
        - pr_opened
        - commit_authored

Each listed slug corresponds to an activity definition created by your plugins. Only matching definitions will appear as columns in the table, showing per-contributor counts and icons.

When this configuration is omitted, no per-activity breakdown columns are shown — contributors are listed with their total points and trend only.

Role Configuration

Roles categorize contributors and can be filtered in the leaderboard.

Example:

leaderboard:
  roles:
    core:
      name: Core Team
      description: Full-time team members

    intern:
      name: Intern
      description: Internship participants

    contributor:
      name: Open Source Contributor
      description: Community contributors

    bot:
      name: Bot Account
      description: Automated accounts
      hidden: true # Exclude from leaderboard

Plugin Configuration

Plugins extend the system with new data sources.

Basic Plugin:

leaderboard:
  plugins:
    github:
      name: GitHub Activity Tracker
      source: https://example.com/plugins/github.js
      config:
        githubToken: ${{ env.GITHUB_TOKEN }}
        githubOrg: myorg
        repositories:
          - repo1
          - repo2

Local Plugin:

leaderboard:
  plugins:
    custom:
      source: file:///absolute/path/to/plugin.js
      config:
        apiKey: ${{ env.API_KEY }}

Environment Variables

In Config

Use environment variables in config.yaml:

leaderboard:
  plugins:
    github:
      config:
        token: ${{ env.GITHUB_TOKEN }}
        org: ${{ env.GITHUB_ORG }}

System Variables

Set these in your environment:

# Data directory location
export LEADERBOARD_DATA_DIR=/path/to/data-repo

# Database URL (optional)
export LIBSQL_DB_URL=file:/path/to/custom.db

# Plugin-specific variables
export GITHUB_TOKEN=ghp_xxx
export SLACK_API_TOKEN=xoxb-xxx

Social Profiles

Map social platform identifiers to Lucide icons:

leaderboard:
  social_profiles:
    github:
      icon: github
    linkedin:
      icon: linkedin
    twitter:
      icon: twitter
    email:
      icon: mail
    website:
      icon: globe

Then in contributor profiles:

---
username: alice
social_profiles:
  github: https://github.com/alice
  linkedin: https://linkedin.com/in/alice
---

Top Contributors

Highlight specific activity types in the sidebar:

leaderboard:
  top_contributors:
    - pr_merged
    - issue_opened
    - release_published

Custom Aggregates

Define custom statistics to display:

leaderboard:
  aggregates:
    global: # Home page stats
      - total_activities
      - count_contributors
      - pr_avg_tat # Custom aggregate

    contributor: # Profile page stats
      - total_points
      - total_activities
      - streak_days # Custom aggregate

Aggregates must be computed by plugins or in the Next.js app.

Badge Configuration

Define badge definitions and evaluation rules under leaderboard.badges:

Badge Definitions

Each badge has a slug, display name, description, and one or more variants (tiers):

leaderboard:
  badges:
    definitions:
      - slug: activity_milestone
        name: Activity Milestone
        description: Awarded for completing activities
        variants:
          bronze:
            description: Completed 256 activities
            svg_url: https://example.com/badges/activity-bronze.svg
          silver:
            description: Completed 1024 activities
            svg_url: https://example.com/badges/activity-silver.svg
            order: 1
          gold:
            description: Completed 4096 activities
            svg_url: https://example.com/badges/activity-gold.svg
            order: 2

Each variant has:

  • description — What it means to earn this tier
  • svg_url — URL to the badge SVG image
  • order (optional) — Display order (higher = more prestigious)

Badge Rules

Rules define how badges are evaluated and awarded. Four rule types are supported:

Threshold Rules

Award badge variants when an aggregate value exceeds thresholds:

rules:
  - type: threshold
    badge_slug: activity_milestone
    aggregate_slug: activity_count
    thresholds:
      - variant: bronze
        value: 256
      - variant: silver
        value: 1024
      - variant: gold
        value: 4096

Streak Rules

Award badges for consecutive days (or weeks/months) with activity:

- type: streak
  badge_slug: consistency_champion
  streak_type: daily # daily | weekly | monthly
  activity_definitions: # optional — all activities if omitted
    - pr_merged
    - pr_opened
  thresholds:
    - variant: bronze
      days: 7
    - variant: silver
      days: 14
    - variant: gold
      days: 30

Growth Rules

Award badges for percentage increases in aggregate values over a period:

- type: growth
  badge_slug: rising_star
  aggregate_slug: total_activity_points
  period: month # week | month | year
  thresholds:
    - variant: bronze
      percentage_increase: 25
    - variant: silver
      percentage_increase: 50
    - variant: gold
      percentage_increase: 100

Composite Rules

Award a single variant when multiple aggregate conditions are met:

- type: composite
  badge_slug: well_rounded
  operator: AND # AND | OR
  variant: gold
  conditions:
    - aggregate_slug: activity_count
      operator: ">="
      value: 100
    - aggregate_slug: total_activity_points
      operator: ">="
      value: 500

All rules support an optional enabled: false flag to temporarily disable evaluation without removing the rule.

Plugins can also provide additional badge definitions and rules via their manifest. See the plugin API reference for details.

Theme Customization

Override the default theme:

leaderboard:
  theme: https://raw.githubusercontent.com/myorg/data/main/theme.css

The theme CSS file can override any CSS variables or classes.

Role Badge Colors

Role badges render with a data-contributor-role attribute set to the role key (e.g., core, intern, contributor). You can customize badge colors per role in your theme.css:

/* Style badges for the "core" role */
[data-contributor-role="core"] {
  background-color: oklch(0.65 0.18 145);
  color: white;
}

/* Style badges for the "intern" role */
[data-contributor-role="intern"] {
  background-color: oklch(0.7 0.15 250);
  color: white;
}

/* Style badges for the "contributor" role */
[data-contributor-role="contributor"] {
  background-color: oklch(0.75 0.12 60);
  color: black;
}

Use any valid CSS for styling — background-color, color, border, etc. The attribute selector [data-contributor-role="<role_key>"] matches the role keys defined in your config.yaml under leaderboard.roles.

Validation

Config is validated at runtime using Zod schemas. Invalid configurations will fail with detailed error messages:

Configuration validation failed:
  - org.url: Invalid url
  - leaderboard.roles: Required
  - leaderboard.plugins.github.source: Invalid url

Complete Example

org:
  name: Acme Corp
  description: Building amazing products
  url: https://acme.com
  logo_url: https://acme.com/logo.svg
  socials:
    github: https://github.com/acme

meta:
  title: Acme Contributors
  description: Recognizing our amazing contributors
  image_url: https://acme.com/og.png
  site_url: https://contributors.acme.com
  favicon_url: https://acme.com/favicon.ico

leaderboard:
  roles:
    employee:
      name: Employee
    contractor:
      name: Contractor
    contributor:
      name: Open Source Contributor

  top_contributors:
    - pr_merged
    - release_published

  leaderboard:
    all_contributors:
      activity_definitions:
        - pr_merged
        - pr_opened
        - commit_authored

  social_profiles:
    github:
      icon: github
    linkedin:
      icon: linkedin

  data_explorer:
    source: https://acme.github.io/leaderboard-data/data.db

  badges:
    definitions:
      - slug: activity_milestone
        name: Activity Milestone
        description: Awarded for completing activities
        variants:
          bronze:
            description: Completed 100 activities
            svg_url: https://acme.com/badges/activity-bronze.svg
          gold:
            description: Completed 1000 activities
            svg_url: https://acme.com/badges/activity-gold.svg
    rules:
      - type: threshold
        badge_slug: activity_milestone
        aggregate_slug: activity_count
        thresholds:
          - variant: bronze
            value: 100
          - variant: gold
            value: 1000

  plugins:
    github:
      source: https://cdn.acme.com/plugins/github.js
      config:
        token: ${{ env.GITHUB_TOKEN }}
        org: acme
        repos:
          - frontend
          - backend

    slack:
      source: https://cdn.acme.com/plugins/slack.js
      config:
        token: ${{ env.SLACK_TOKEN }}
        channel: ${{ env.SLACK_CHANNEL }}