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

@zevanoo/hmr

v1.1.0

Published

**Lightweight, flexible, and production-ready Hot Module Replacement (HMR) for Node.js (ESM/CJS).**

Readme

@zevanoo/hmr

Lightweight, flexible, and production-ready Hot Module Replacement (HMR) for Node.js (ESM/CJS).

In modern Node.js development, especially with ECMAScript Modules (ESM), module caching is a persistent hurdle. Once a file is imported, Node.js caches it in memory for the lifetime of the process. @zevanoo/hmr solves this by providing a centralized registry to dynamically load, update, and remove modules without restarting your application.

This library is ideal for long-running processes that require rapid iteration or "live" logic updates, such as:

  • Bot Platforms (WhatsApp, Discord, Telegram) for instant command updates.
  • API Servers requiring endpoint updates without dropping active socket connections.
  • Automation Systems where logic scripts change frequently at runtime.
  • Worker Threads processing tasks based on dynamic user-provided scripts.

Key Features

  • 🚀 Zero-Restart Runtime: Update functions, variables, or objects in real-time.
  • 📂 Multi-Directory Support: Monitor multiple directories simultaneously with unique configurations.
  • Environment Aware: Full HMR in development mode, optimized static one-time loading in production.
  • 📡 Event Driven: Built on EventEmitter to handle add, change, and unlink events.
  • 🛡️ Intelligent Cleanup: Automatically purges memory references (registry) when a file is deleted.
  • 🎨 Flexible Logging: Supports both global and local (per-folder) custom loggers with timestamps.
  • 🔒 Type Safe: Written in TypeScript with full Intellisense support.

Installation

npm install @zevanoo/hmr

Quick Start

1. Initialization

Initialize the HMR instance in your application's entry point (e.g., index.js or main.ts).

import HMR from '@zevanoo/hmr';

const hmr = new HMR(
    { 
        watchDir: './src/utils', 
        ignoreFiles: ['formatter.js'] 
    },
    { 
        watchDir: './src/libs' 
    },
    // Final Argument: Global Logger (Optional)
    (time, level, msg) => {
        console.log(`[${time}] [HMR-SYSTEM] ${level.toUpperCase()}: ${msg}`);
    }
);

export default hmr;

2. Accessing Modules

You can access exported members via the .get() method or directly through the modules Proxy.

import hmr from './index.js';

// Option 1: Specific member access (Destructuring)
const { toNumber, isValid } = hmr.get(['toNumber', 'isValid']);
if (toNumber) console.log(toNumber("100"));

// Option 2: Direct access via Proxy (Recommended for concise code)
const myCommand = hmr.modules.pingCommand;
if (myCommand) myCommand.execute();

Event Emitter

Since the library extends Node.js EventEmitter, you can attach listeners to trigger side effects when files change.

// Triggered when a new file is found
hmr.on('add', (filePath, module) => {
    console.log(`New module registered: ${filePath}`);
});

// Triggered when an existing file is edited and reloaded
hmr.on('change', (filePath, module) => {
    console.log(`Module updated: ${module.name}`);
});

// Triggered when a file is deleted from disk
hmr.on('unlink', (filePath) => {
    console.log(`Module removed: ${filePath}`);
});

Runtime Behavior

The library automatically adjusts its strategy based on process.env.NODE_ENV:

Development (NODE_ENV=development)

  • Watcher: Active (powered by chokidar).
  • Cache Busting: Appends a ?update=timestamp query string to every dynamic import to bypass the Node.js ESM cache.
  • Logs: Detailed synchronization logs.

Production (NODE_ENV=production)

  • Watcher: Disabled. Modules are scanned and loaded recursively exactly once during startup.
  • Performance: Uses standard Node.js internal caching for maximum RAM and CPU efficiency.
  • Logs: Minimalist (only critical errors).

API Configuration

new HMR(...folderConfigs, globalLogger?)

Folder Configuration Object

| Property | Type | Description | | :--- | :--- | :--- | | watchDir | string | Required. Path to the folder to monitor. Supports recursive sub-folders. | | ignoreFiles | string[] | List of filenames/suffixes to ignore (e.g., ['.test.js']). | | logger | function | Local logger specific to this folder. If provided, it overrides the global logger. |

Logger Callback Function

(time, level, msg) => void

  • time: Current locale time string.
  • level: 'info' | 'warn' | 'error'.
  • msg: The message content.

License

MIT


Important Note on Sub-Folders

HMR recursively watches sub-folders within your watchDir. Because this library uses a Flat Registry (all exports are stored in a single Map), please ensure your export names are unique across all watched files to avoid naming collisions.