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

zihooks

v2.0.0

Published

Hooks store commands and data

Readme

Zihooks

A lightweight singleton management library for Discord.js bots and applications. Zihooks provides a clean way to manage and access singleton instances of commonly used services like client, database, logger, and command handlers across your application.

npm License: ISC

Features

  • 🎯 Singleton Pattern: Ensures only one instance of each service exists throughout your application
  • 🔗 Easy Access: Simple hook-based API to access services from anywhere
  • 🎮 Discord.js Integration: Seamless integration with Discord.js
  • 📊 Type Safety: Full TypeScript type definitions included
  • 🛠️ Flexible: Support for custom services via useHooks and useStore

Installation

Install via npm or yarn:

npm install zihooks

or

yarn add zihooks

Quick Start

const { useClient, useCommands, useLogger } = require("zihooks");
const { Client } = require("discord.js");
const winston = require("winston");

// Initialize services (first call with the instance)
const client = useClient(new Client({ intents: [] }));
const commands = useCommands(new Map());
const logger = useLogger(winston.createLogger({}));

// Access services from anywhere (subsequent calls)
const myClient = useClient(); // Returns the same instance
const myCommands = useCommands();
const myLogger = useLogger();

Available Hooks

Service Hooks

| Hook | Purpose | Example | | -------------- | ------------------------------ | ------------------------------- | | useClient | Discord.js Client instance | useClient(discordClient) | | useCommands | Command storage and management | useCommands(commandMap) | | useFunctions | Function registry | useFunctions(functionMap) | | useCooldowns | Cooldown management | useCooldowns(cooldownMap) | | useLogger | Winston logger instance | useLogger(logger) | | useDB | Database connection | useDB(databaseConnection) | | useConfig | Application configuration | useConfig(configObject) | | useStatus | Status management | useStatus(statusMap) | | useAI | AI service instance | useAI(aiService) | | useUntil | Utility service | useUntil(untilService) | | useGiveaways | Giveaway manager | useGiveaways(giveawayManager) | | useWelcome | Welcome message handler | useWelcome(welcomeMap) | | useResponder | Response handler | useResponder(responderMap) |

Storage Hooks

Method 1: Direct Map Access

const { useHooks, useStore } = require("zihooks");

// useHooks - for managing hook configurations
useHooks.set("myHook", { name: "example" });
const myHook = useHooks.get("myHook");

// useStore - for storing generic data
useStore.set("myData", { count: 42 });
const myData = useStore.get("myData");

Method 2: Chained Map Methods

const { useHooks, useStore } = require("zihooks");

// useHooks - chain get() and set() operations
useHooks.set("config", { debug: true });
useHooks.set("version", "2.0.0");

const config = useHooks.get("config"); // { debug: true }
const version = useHooks.get("version"); // "2.0.0"

// useStore - chain operations
useStore.set("cache", { timestamp: Date.now() });
useStore.get("cache"); // { timestamp: ... }

// Check if key exists before getting
if (useHooks.has("config")) {
	const config = useHooks.get("config");
}

// Delete entries
useHooks.delete("oldKey");
useStore.clear(); // Clear all entries

Usage Examples

Initialize Services at Startup

const { useClient, useCommands, useLogger } = require("zihooks");
const { Client } = require("discord.js");

// In your main bot file
const client = new Client({ intents: ["Guilds", "GuildMessages", "DirectMessages"] });
const commands = new Map();
const logger = require("./logger"); // your winston logger

// First initialization (must provide the instance)
useClient(client);
useCommands(commands);
useLogger(logger);

client.login(process.env.TOKEN);

Access Services Anywhere

// In any other file, no need to import the instances directly
const { useClient, useCommands, useLogger } = require("zihooks");

function myFunction() {
	const client = useClient(); // Get the stored client
	const commands = useCommands(); // Get the stored commands
	const logger = useLogger(); // Get the stored logger

	logger.info("Processing with client and commands");
}

Extended Message Interaction

const { modinteraction } = require("zihooks");

client.on("messageCreate", async (message) => {
	// Extend message with interaction-like features
	await modinteraction(message);

	// Now you can use:
	console.log(message.getText()); // Get message text
	console.log(message.getArgs()); // Get message arguments
	console.log(message.getUserId()); // Get mentioned user IDs
	console.log(message.getUsers()); // Get User objects
	console.log(message.isOwner()); // Check if sender is owner

	if (message.hasPermission("ADMINISTRATOR")) {
		// Handle admin commands
	}
});

Message Helper Methods

The modinteraction function extends Discord.js Message objects with additional utilities:

Content Helpers

  • getText() - Get normalized message content
  • getArgs() - Get message as array of arguments
  • hasText(text) - Check if message contains text

Mention Extractors

  • getUserId() - Extract user IDs from mentions
  • getChannelId() - Extract channel IDs from mentions
  • getRoleId() - Extract role IDs from mentions
  • getAllMentions() - Get all mentions as object

Object Resolvers

  • getUsers() - Resolve User objects from mentions
  • getChannels() - Resolve Channel objects from mentions
  • getRoles() - Resolve Role objects from mentions

Permission Helpers

  • isOwner() - Check if sender is bot owner
  • hasPermission(perm) - Check if user has permission

State Helpers

  • isDM() - Check if message is in DMs
  • isGuild() - Check if message is in a guild

Cooldown Management

const cooldowns = new Map();

message.cooldown(cooldowns, 3000); // 3 second cooldown

Important Notes

⚠️ Initialization: Each hook must be initialized with an instance on first call. Subsequent calls without arguments return the cached instance.

// First call - MUST provide the instance
const commands = useCommands(new Map());

// Subsequent calls - no argument needed
const commands = useCommands(); // Returns same instance

// Without initialization
const commands = useCommands(); // Returns false and logs error

API Reference

customMap

Extended Map class for storing hook data:

const { useCommands } = require("zihooks");
const commands = useCommands(new customMap());

CommandInteraction

Extended Message interface that behaves like Discord Interaction:

interface CommandInteraction extends Message {
	user: User;
	guildId: string | null;

	deferReply(): Promise<boolean>;
	editReply(content: string | object): Promise<Message>;
	followUp(content: string | object): Promise<Message>;
	replyEphemeral(content: string | object): Promise<Message | false>;
	// ... additional methods
}

Best Practices

  1. Initialize on Startup: Initialize all required services in your main bot file
  2. Consistent Usage: Always use the same hook name throughout your application
  3. Error Handling: Check for false returns if hooks might not be initialized
  4. Type Definitions: Use TypeScript for better IDE autocomplete and type safety
  5. Lazy Loading: Initialize services only when needed to improve startup time

Contributing

Contributions are welcome! Please feel free to submit a Pull Request to the GitHub repository.

License

This project is licensed under the ISC License. See the LICENSE file for more details.