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

@neozmmv/cord

v0.1.1

Published

A minimal Discord bot library

Readme

cord

⚠️ Work in progress. cord is in early development — APIs may change and not all features are stable yet.

A minimal Discord bot library built directly on top of the Discord API — no abstractions you didn't ask for.

import { Bot } from '@neozmmv/cord';

const bot = new Bot(process.env.TOKEN!);

bot.addCommand('ping', 'Replies with Pong!', async (ctx) => {
  await ctx.sendMessage(`Pong! Hey ${ctx.user.username}`);
});

await bot.run();

Why cord?

Most Discord libraries hide everything. cord gives you a clean API without taking away control.

  • No manual command registrationaddCommand handles it automatically on startup
  • No boilerplate — one file, one bot, done
  • TypeScript-first — full autocomplete on ctx, commands, and payloads
  • Direct API — built on raw WebSocket + REST, no hidden magic
  • Event system — listen to any Discord Gateway event with full type safety

Installation

bun add @neozmmv/cord
# or
npm install @neozmmv/cord

Requires Bun or Node.js 18+


Getting Started

1. Create a bot on the Discord Developer Portal

2. Set up your .env:

TOKEN=your_bot_token_here

3. Create your bot:

import { Bot } from '@neozmmv/cord';

const bot = new Bot(process.env.TOKEN!);

bot.addCommand('ping', 'Check if the bot is alive', async (ctx) => {
  await ctx.sendMessage('Pong!');
});

await bot.run();
console.log(`Online as ${bot.user?.username}`);

Commands

bot.addCommand(name, description, handler, guildId?)

Registers a slash command. Pass a guildId to register instantly in a specific server, or omit it for global registration (up to 1 hour to propagate).

// global command
bot.addCommand('help', 'Shows help', async (ctx) => {
  await ctx.sendMessage('Here is the help menu...');
});

// guild-only (instant)
bot.addCommand('admin', 'Admin only', async (ctx) => {
  await ctx.sendMessage('Admin panel');
}, process.env.GUILD_ID);

Command names must be lowercase and can only contain letters and numbers.

Chaining

bot
  .addCommand('ping', 'Ping the bot', pingHandler)
  .addCommand('help', 'Show help', helpHandler)
  .addCommand('info', 'Server info', infoHandler);

Context (slash commands)

Every command handler receives a ctx object:

bot.addCommand('info', 'Get info', async (ctx) => {
  ctx.commandName        // "info"
  ctx.user.username      // who used the command
  ctx.user.id            // their Discord ID
  ctx.guildId            // server ID
  ctx.channelId          // channel ID
  ctx.channel.name       // channel name
  ctx.locale             // user's locale ("en-US", "pt-BR", ...)

  await ctx.sendMessage('Hello!');
  await ctx.sendMessage('Only you can see this!', { ephemeral: true });
  await ctx.editMessage('Updated message!');
});

Events

Listen to any Discord Gateway event with bot.on(). Every event is fully typed — autocomplete works out of the box.

import { Bot, Event } from '@neozmmv/cord';

bot.on(Event.MESSAGE_CREATE, async (ctx) => {
  if (ctx.content === '!hello') {
    const msgId = await ctx.sendMessage(`Hello, ${ctx.author.global_name}!`);
    await ctx.editMessage(msgId, 'Edited!');
  }
});

bot.on(Event.GUILD_MEMBER_ADD, (ctx) => {
  console.log(`New member: ${ctx.user.username}`);
});

Multiple handlers for the same event are supported:

bot.on(Event.MESSAGE_CREATE, handlerOne);
bot.on(Event.MESSAGE_CREATE, handlerTwo); // both will be called

Available Events

Event.READY
Event.RESUMED
Event.CHANNEL_CREATE / UPDATE / DELETE / PINS_UPDATE
Event.GUILD_CREATE / UPDATE / DELETE
Event.GUILD_BAN_ADD / REMOVE
Event.GUILD_EMOJIS_UPDATE / STICKERS_UPDATE
Event.GUILD_MEMBER_ADD / UPDATE / REMOVE
Event.MESSAGE_CREATE / UPDATE / DELETE / DELETE_BULK
Event.MESSAGE_REACTION_ADD / REMOVE / REMOVE_ALL
Event.PRESENCE_UPDATE
Event.TYPING_START
Event.VOICE_STATE_UPDATE / SERVER_UPDATE
Event.INTERACTION_CREATE
Event.THREAD_CREATE / UPDATE / DELETE / MEMBER_UPDATE

Message Context

Handlers for Event.MESSAGE_CREATE receive a MessageContext with helper methods:

bot.on(Event.MESSAGE_CREATE, async (ctx) => {
  ctx.content          // message content
  ctx.author.username  // who sent the message
  ctx.channelId        // channel ID
  ctx.guildId          // server ID

  const msgId = await ctx.sendMessage('Pong!');
  await ctx.editMessage(msgId, 'Pong! (edited)');
});

Intents

cord includes sensible defaults — Guilds, GuildMessages, MessageContent, and GuildMembers. You can customize:

import { Bot, Intent } from '@neozmmv/cord';

// use defaults
const bot = new Bot(process.env.TOKEN!);

// custom intents
const bot = new Bot(process.env.TOKEN!, [
  Intent.Guilds,
  Intent.GuildMessages,
  Intent.GuildVoiceStates,
]);

// extend defaults
const bot = new Bot(process.env.TOKEN!, [
  ...Bot.DEFAULT_INTENTS,
  Intent.GuildVoiceStates,
]);

Some intents like MessageContent and GuildMembers are privileged and must be enabled in the Discord Developer Portal.


How it works

cord connects directly to the Discord Gateway via WebSocket and manages the full lifecycle:

connect → HELLO → IDENTIFY → READY → register commands → listen for events

The heartbeat is handled automatically — your bot stays connected.


License

MIT