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

modu-cord

v1.0.0

Published

Discord.js wrapper for a module-based way to implement Discord bot features.

Readme

Table of contents

About

ModuCord is a simple wrapper around the discord.js JavaScript library which tries to simplify and increase structure for typical bot development. Using TypeScript is highly recommended.

The idea of ModuCord is to increase structure by dividing the bot functionality into logical modules. Each module can contain zero, one or multiple commands as well as multiple module handlers for business logic that is not bound to a command (eg. experience system, telemetry, interactive reactions, etc.).

Installation

Be sure to also view the installation guide for discord.js.

npm: npm install modu-cord

yarn (recommended): yarn add modu-cord

ModuCord comes with type definitions out of the box, so no additional types package needs to be installed.

Example Usage

PingCommand.ts

import { ICommand, CommandEvent, IBotClient, CommandValidationResult } from 'modu-cord'

export default class PingCommand implements ICommand {

	// The main command name
	readonly name = 'ping'

	// Aliases that also triggers the command
	readonly aliases = ['pong', 'ping-pong']

	// A description, which should describe the resposibility of this command.
	// This is also useful for a help command or something similar.
	readonly description = 'A ping pong command.'

	// This function gets called when the validation was successful.
	// This is where the actually command handling should be done.
	async execute(event: CommandEvent, bot: IBotClient): Promise<void> {
		await event.reply('Pong!')
	}

	// Runs before execute function.
	// Only runs the execute function if it returns a positive CommandValidationResult.
	// It is still possible to reply to the message inside here,
	// since the idea is to decouple the error handling / validation
	// from the actual command processing.
	async validate(event: CommandEvent, bot: IBotClient): Promise<CommandValidationResult> {
		if (event.args.length === 0)
			return new CommandeValidationResult(true)
		
		// Replying with whats wrong
		await event.reply('Invalid argument length')
		return new CommandValidationResult(false, 'Invalid argument length')
	}
}

UtilityModuleHandler.ts

import { IModuleHandler, IBotClient } from 'modu-cord'

export default class UtilityModuleHandler implements IModuleHandler {

	// This is used to setup the handler,
	// by for example establishing a database connection or defining event callbacks.
	// A module handler has full access to the DiscordBotClient via the bot parameter.
	async setup(bot: IBotClient): Promise<void> {
		bot.client.on('guildMemberAdd', (member) => {
			if (member.user)
				console.log('User joined server:', member.user.tag)
		})
	}
}

UtilityModule.ts

import { IModue } from 'modu-cord'
import PingCommand from './PingCommand'
import UtilityModuleHandler from './UtilityModuleHandler'


export default class UtilityModule implements IModule {

	// The id needs to be unique between modules
	readonly id = 1
	readonly name = 'Utility'
	readonly description = 'Offers some utility functionality.'
	readonly handlers = [ new UtilityModuleHandler() ]
	readonly commands = [ new PingCommand() ]

}

index.ts

import { DiscordBotClient } from 'modu-cord'
import UtilityModule from './UtilityModule'

// This is just for the sake of simplicity.
// I highly recommend to save the bot token outside your
// source code (eg. a config file which is ignored by git).
const token = 'YOUR_BOT_TOKEN'
const bot = new DiscordBotClient()

// Modules should be added after the login process finishes,
// in case the setup method of a module handler needs access to the logged in client.
async function init(): Promise<void> {
	await bot.login(token)

	if (await bot.addModule(new UtilityModule()))
		console.log('UtilityModule added successfully.')
}

init()

Final Words

This is my very first open source project that I am trying to maintain, so constructive feedback is highly appreciated. If any questions arise, don't hesitate to open an issue here or ask me on Discord.

Discord tag: Bakuenjin#0001