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

invitron

v1.0.1

Published

A powerful Discord.js invite tracker with persistent storage, member analytics, vanity URL support, and comprehensive join monitoring system for Discord bots.

Readme

Invitron Logo

A powerful Discord.js invite tracker with persistent storage and comprehensive analytics

NPM Version NPM Downloads NPM License Discord GitHub Stars

🎯 Track member joins and leaves via invites  
📝 Support for normal, vanity, and audit-log based invites  
💾 Optional persistent JSON storage with analytics
📊 Built-in leaderboards and comprehensive statistics

InstallationQuick StartDocumentationExamples


✨ Features

  • 🌐 Complete Invite Tracking - Monitor all guild member joins and leaves
  • 📊 Advanced Analytics - Leaderboards, statistics, and detailed invite data
  • 🤖 Bot-Friendly - Optional bot filtering and comprehensive error handling
  • 💾 Persistent Storage - Local JSON file storage with automatic data management
  • 🔄 Real-time Updates - Automatic invite cache management and event handling
  • 🛡️ Multiple Sources - Support for normal invites, vanity URLs, and audit logs
  • 🧪 Debug Support - Comprehensive logging for easier troubleshooting
  • TypeScript Ready - Fully typed with excellent IDE support
  • 🎛️ Highly Configurable - Flexible options for different use cases

📦 Installation

# Using npm
npm install invitron

# Using yarn  
yarn add invitron

# Using pnpm
pnpm add invitron

Requirements:

  • Node.js 16.9.0 or higher
  • Discord.js v14.11.0 or higher

🚀 Quick Start

Basic Setup

import { Client, GatewayIntentBits } from "discord.js";
import InvitesTracker from "invitron";

const client = new Client({ 
  intents: [
    GatewayIntentBits.Guilds, 
    GatewayIntentBits.GuildMembers, 
    GatewayIntentBits.GuildInvites
  ] 
});

// Initialize the tracker
const tracker = InvitesTracker.init(client, {
  fetchGuilds: true,      // Load existing invites on startup
  fetchVanity: true,      // Track vanity URL joins
  fetchAuditLogs: true,   // Use audit logs as fallback
  ignoreBots: true,       // Ignore bot joins
  deductOnLeave: true,    // Remove invite credit when members leave
  storage: { 
    enabled: true, 
    path: "./data/invites.json" 
  }
});

// Listen for member joins
tracker.on("guildMemberAdd", (member, joinData) => {
  const { inviter, code, totalInvites, type } = joinData;
  
  if (type === "normal" && inviter) {
    console.log(`👋 ${member.user.tag} joined using ${inviter.tag}'s invite (${code})`);
    console.log(`📊 ${inviter.tag} now has ${totalInvites} total invites`);
  }
});

client.login("YOUR_BOT_TOKEN");

Advanced Usage

// Get user's invite statistics
const userInvites = tracker.getInvites(guildId, userId);
console.log(`User has ${userInvites} invites`);

// Get server leaderboard
const leaderboard = tracker.getLeaderboard(guildId, 10);
leaderboard.forEach((entry, index) => {
  console.log(`${index + 1}. User ${entry.userId}: ${entry.invites} invites`);
});

// Get top inviter
const topInviter = tracker.getTopInviter(guildId);
if (topInviter) {
  console.log(`🏆 Top inviter: ${topInviter.userId} with ${topInviter.invites} invites`);
}

// Reset guild data
tracker.resetGuild(guildId);

📖 API Reference

InvitesTracker.init(client, options)

Initializes the invite tracker with the specified Discord client and options.

Parameters

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | client | Client | - | Discord.js client instance | | options | TrackerOptions | {} | Configuration options |

TrackerOptions

| Option | Type | Default | Description | |--------|------|---------|-------------| | fetchGuilds | boolean | false | Preload invites from all guilds on startup | | fetchVanity | boolean | false | Track joins via vanity URLs | | fetchAuditLogs | boolean | false | Use audit logs when invite source is unknown | | debug | boolean | false | Enable debug logging | | ignoreBots | boolean | false | Ignore bot joins/leaves | | deductOnLeave | boolean | false | Subtract invite count when members leave | | storage.enabled | boolean | false | Enable persistent storage | | storage.path | string | "./invites.json" | Path to storage file |

Methods

getInvites(guildId: string, userId: string): number

Returns the total number of invites for a user in the specified guild.

resetGuild(guildId: string): void

Resets all invite data for the specified guild.

getTopInviter(guildId: string): { userId: string; invites: number } | null

Returns the user with the most invites in the guild.

getLeaderboard(guildId: string, limit?: number): Array<{ userId: string; invites: number }>

Returns a sorted leaderboard of inviters (default limit: 10).

Events

guildMemberAdd

Emitted when a member joins a guild.

  • member: The member who joined
  • joinData: Detailed information about the join

guildMemberRemove

Emitted when a member leaves a guild.

  • member: The member who left

💡 Examples

Discord Bot Command Example

// !invites command
if (message.content === "!invites") {
  const userId = message.author.id;
  const guildId = message.guild!.id;
  const invites = tracker.getInvites(guildId, userId);
  
  message.reply(`You have **${invites}** invites! 🎉`);
}

// !leaderboard command  
if (message.content === "!leaderboard") {
  const guildId = message.guild!.id;
  const leaderboard = tracker.getLeaderboard(guildId, 5);
  
  let response = "🏆 **Top Inviters:**\n";
  leaderboard.forEach((entry, index) => {
    const user = client.users.cache.get(entry.userId);
    response += `${index + 1}. ${user?.tag || 'Unknown'}: ${entry.invites} invites\n`;
  });
  
  message.reply(response);
}

Slash Command Example

// Register slash command
const invitesCommand = {
  name: 'invites',
  description: 'Check your invite count',
  options: [{
    name: 'user',
    description: 'User to check (optional)',
    type: 6, // USER type
    required: false
  }]
};

// Handle slash command
client.on('interactionCreate', async (interaction) => {
  if (!interaction.isChatInputCommand() || interaction.commandName !== 'invites') return;
  
  const targetUser = interaction.options.getUser('user') || interaction.user;
  const invites = tracker.getInvites(interaction.guildId!, targetUser.id);
  
  await interaction.reply(`${targetUser.tag} has **${invites}** invites! 🎯`);
});

🔧 Configuration Examples

Minimal Setup

const tracker = InvitesTracker.init(client);

Production Setup

const tracker = InvitesTracker.init(client, {
  fetchGuilds: true,
  fetchVanity: true,
  fetchAuditLogs: true,
  ignoreBots: true,
  deductOnLeave: true,
  storage: {
    enabled: true,
    path: process.env.DATA_PATH || "./data/invites.json"
  }
});

Development Setup

const tracker = InvitesTracker.init(client, {
  debug: true,
  fetchGuilds: true,
  storage: { enabled: true }
});

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the Apache-2.0 License - see the LICENSE file for details.


🆘 Support


Made with ❤️ by boda335