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

@azurioh/discord-kernel

v0.1.0

Published

Framework kernel for Discord bots: command DSL, guards, interaction routing, composed components, i18n, ports (Presenter, Logger, DatabaseConnection, Authorizer, Scheduler).

Readme

@azurioh/discord-kernel

The framework half of a Discord bot, without the bot: a command DSL, guards, interaction routing, composed components, localisation, and the ports an application implements. It knows discord.js and nothing else — no database, no logger implementation, no opinion about what your bot does.

Built for Clean Architecture with vertically-sliced feature modules: the kernel is the innermost ring, and the fact that it is a package rather than a folder is what enforces that — an outer ring simply is not in its dependency graph.

pnpm add @azurioh/discord-kernel discord.js

discord.js is a peer dependency, never a dependency: two copies of the library in one tree would break every instanceof the gateway relies on.

What is in it

| Area | What it gives you | | ---- | ----------------- | | discord/command/ | createCommand (flat or grouped), typed options, guards (allOf/anyOf, permissions, roles, cooldowns), the per-interaction Context, autocomplete, the CommandRouter | | discord/interaction/ | createButton, createModal, the four typed select menus (createStringSelect, createChannelSelect, createRoleSelect, createUserSelect), the InteractionRouter/InteractionDispatcher seam | | discord/components/ | ComponentRouter for persistent customId routing, and collector-backed screens: paginator, interactive-message, settings-editor | | discord/events/ | createEvent and the EventRouter — the one place client.on is called | | discord/ui/ | Embeds with Discord's size limits handled, createCard containers, a configurable palette, a colour-input parser | | i18n/ | Catalogs ({ en, fr? }, en mandatory), a registry that fails the boot on a duplicate key, per-interaction locale resolution | | authz/ | An Authorizer port with viewer/editor grants and a requireLevel guard | | errors/ | BusinessError and friends, carrying an optional translation key beside the English source | | scheduler/ | A Scheduler port and a node-cron implementation | | Ports | Logger, DatabaseConnection, Presenter, Clock, ChannelExporter — declared here, implemented by your app |

Every path is imported directly; there is no root barrel:

import { createCommand } from "@azurioh/discord-kernel/discord/command/create-command";
import type { Logger } from "@azurioh/discord-kernel/logger";
import { type Catalog, createTranslator } from "@azurioh/discord-kernel/i18n";

What is deliberately not in it

  • A database. DatabaseConnection is a lifecycle port — connect, close — and nothing more. Query APIs differ too much between engines to abstract usefully, so an adapter exposes its own and your repositories are the only code that touches it.
  • A logger. Logger is a port; pino, Sentry or console live in your app.
  • A configuration shape. The kernel ships env-reading primitives (requireEnv, enumEnv, …); which keys exist is your composition root's call.
  • A palette. Embeds render in Discord's blurple until you say otherwise, so a bot never starts out wearing someone else's identity.

Making it yours

Two things are global by nature — a bot has one look, decided once — and are set from the composition root before any module is constructed:

import { configureEmbedColors } from "@azurioh/discord-kernel/discord/ui/colors";
import { registerColorAliases } from "@azurioh/discord-kernel/discord/ui/color-input";

configureEmbedColors({ brand: 0xf3c909 });
registerColorAliases({ gold: "#f3c909", or: "#f3c909" });

Everything else is injected: your modules are factories receiving a container you define, so nothing in the kernel is reachable as a singleton.

Requirements

Node 22.12+, discord.js 14.27+, TypeScript 5.9. The published build is CommonJS with declaration files, resolved through explicit subpath exports.

License

MIT