mrkeyoor.com_
Wed 23 Sept 00:34 UTC
npmUtilsupdated 21 Sept 2026

stealthy-require review

stealthy-require 1.1.1 temporarily empties Node's process-wide CommonJS cache so one synchronous callback can load a fresh module graph. It then deletes the newly loaded JavaScript entries and copies the previous cache back; an optional second callback preloads dependencies that must remain shared. Version 1.1.1's only code fix stopped `undefined` entries appearing in `require.cache`, and it remains the latest release from May 2017. This is loader-state surgery for legacy CommonJS tests or tooling, not ESM reloading, hot deployment, or per-request isolation.

Verdict

stealthy-require 1.1.1 installed in 0.3 seconds with 0 dependencies, but any thrown callback can leave the process-wide CommonJS cache unrestored. Keep it only for controlled synchronous legacy tests; use a test runner reset API or child process for code that can fail, load asynchronously, or run concurrently.

We installed it

Lab card: what happened when we installed stealthy-requireScreenshot of stealthy-require documentation
Install✓ · 0.3s1 package on disk · 1 MB
ImportESM import works · require() works · CommonJS package
Browser0.6 KBgzipped (1.1 KB minified), bundled with esbuild
Typesno TypeScript types found
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does stealthy-require install cleanly?

Yes. In a fresh container with an empty cache, npm install stealthy-require finished in 0.3s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.

How much does stealthy-require add to a browser bundle?

0.6 KB gzipped (1.1 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does stealthy-require work with both ESM and CommonJS?

Yes. Both import 'stealthy-require' and require('stealthy-require') worked in Node 22 in our run. The package is published as CommonJS.

Does stealthy-require include TypeScript types?

No type declarations were found in our install, so TypeScript users need their own declarations.

stealthy-require or clear-module: which should you use?

clear-module: Use it to evict one named CommonJS module and its descendants rather than snapshotting nearly the whole cache. stealthy-require 1.1.1 installed in 0.3 seconds with 0 dependencies, but any thrown callback can leave the process-wide CommonJS cache unrestored.

When should you not use stealthy-require?

Your code uses ESM or dynamic import(). The package only edits CommonJS require.cache; Node's ESM module map is untouched.

API stability4/5The package has exposed one four-argument function since 1.1.0, and 1.1.1 only fixed undefined entries in `require.cache`. With no release after May 2017, the signature will not surprise a pinned legacy caller. The operational contract is less steady than the function shape: it relies on CommonJS cache internals, a positional keep callback, the caller's `module`, synchronous execution, and mutation of a process-global object. Node can load the wrapper today, but the package offers no stated compatibility work for newer loader behavior.
Docs4/5The README walks through the exact cache-clear sequence and explains that native addons stay cached, lazy requires are not fresh, selected dependencies can be preserved, and repeated loads retain objects through `module.children`. It also provides its historical Webpack and Browserify recipes. That candor is useful. The largest missing warning is exception safety: the implementation has no `try/finally`, so a thrown callback skips restoration. There is also no ESM guidance, concurrency model, TypeScript declaration, worker isolation example, or modern bundler verification.
Maintenance1/5npm lists 1.1.1 from May 9, 2017 as the latest version, and GitHub showed 22 stars, 3 open issues and pull requests, an unarchived repository, and a last push on June 11, 2021. The dependency-free implementation is small, but age is relevant because it manipulates Node loader state. No release addresses ESM, exception-safe restoration, current test runners, or recent bundlers. Treat the project as dormant code that remains installed transitively, not as an actively evolving module-isolation tool.
Ecosystem2/5The npm endpoint counted 4,263,792 downloads for August 18 through August 24, 2026, a figure more consistent with transitive legacy use than a broad modern integration ecosystem. Our Node 22 loader checks passed and the package has no dependencies, yet it ships no types and understands only CommonJS cache state. Jest, Vitest, Node test workers, ESM loaders, worker threads, and child-process isolation have their own reset or boundary mechanisms. The README's bundler advice still names Browserify 13.0.1 wrapper internals.

Use it if

  • An existing CommonJS test must instantiate one module and all of its synchronous JavaScript dependencies from a clean cache.
  • You know which database pools, registries, or other singletons must be preserved through the optional keep callback.
  • The load runs in a short-lived process where no other work can require modules concurrently.
  • You are maintaining software that already depends on this package's exact snapshot, clear, and restore sequence.
Skip it if

Setup reality

We installed stealthy-require 1.1.1 in 0.3 seconds in a fresh Node 22 Bookworm sandbox. It left 1 package and 1 MB on disk. npm audit found 0 known vulnerabilities. The package has 0 direct and 0 peer dependencies, is 32 KB unpacked, and declares Node 0.10 or newer. Both CommonJS require() and ESM import loaded, although the package itself is CommonJS with no exports map and contains no TypeScript declarations.

The browser probe measured 1.1 KB minified and 0.6 KB gzipped, but the API still depends on CommonJS cache internals. There are no credentials, native builds, environment variables, or config files. Pass the real require.cache, then perform every fresh require() synchronously inside the callback. The helper snapshots the cache, removes non-.node entries, runs the callback, clears new entries, and restores the original object entries.

That cache is global to the process. Never overlap two calls or run one while other code may load modules. The package has no try/finally; if the load callback or keep callback throws, its restoration steps do not run. An outer cache snapshot can reduce the damage, but a child process is the sound boundary for plugins or unknown code because it also contains globals, timers, native addons, and crashes.

Repeated fresh loads add discarded module objects to the caller's module.children, even after cache restoration. The README tells callers to save and restore that array to avoid retaining every instance. The optional keep callback also requires the caller's module as the fourth argument. Later lazy requires use the restored normal cache. Browserify's documented arguments[5] trick targets version 13.0.1 internals and should not be treated as a current bundler interface.

Patterns

Load a fresh CommonJS dependency tree require-fresh-module

const stealthyRequire = require('stealthy-require');

const freshClient = stealthyRequire(require.cache, () => {
  return require('./client');
});

Every non-native CommonJS module synchronously required by `./client` loads against the temporarily empty cache, not only the top-level file.

Verify that the original cache is restored compare-fresh-instance

const original = require('./counter');
const fresh = stealthyRequire(require.cache, () => require('./counter'));
const restored = require('./counter');

console.log(original === restored); // true
console.log(original === fresh); // false

The fresh object is removed from `require.cache` after the call. A later normal require returns the original cached instance.

Keep one dependency cached preserve-singleton-dependency

const freshApp = stealthyRequire(
  require.cache,
  () => require('./app'),
  () => {
    require('./database-pool');
    require('./metrics-registry');
  },
  module,
);

Both the keep callback and caller's `module` argument are required. Name every singleton whose duplication would be unsafe.

Restore the cache when loading throws restore-cache-after-error

function loadFreshSafely(load) {
  const snapshot = { ...require.cache };
  try {
    return stealthyRequire(require.cache, load);
  } finally {
    for (const id of Object.keys(require.cache)) delete require.cache[id];
    Object.assign(require.cache, snapshot);
  }
}

const plugin = loadFreshSafely(() => require('./plugin'));

The 1.1.1 implementation can skip restoration after an exception because it has no `try/finally`. This outer snapshot helps, but a child process provides a stronger failure boundary.

Remove discarded modules from module.children avoid-child-retention

const childrenBefore = module.children.slice();
try {
  const fresh = stealthyRequire(require.cache, () => require('./worker'));
  fresh.run();
} finally {
  module.children = childrenBefore;
}

Restoring `require.cache` does not remove new entries from `module.children`; save and restore that array during repeated loads.

Read a JSON module without its cached value reload-json-config

const config = stealthyRequire(require.cache, () => {
  return require('./settings.json');
});

A direct `fs.readFile` plus `JSON.parse` is clearer for configuration and avoids clearing unrelated CommonJS modules.

Create isolated module state in a test reset-module-state-test

it('starts from zero', () => {
  const counter = stealthyRequire(require.cache, () => {
    return require('../counter');
  });

  assert.equal(counter.next(), 1);
});

Prefer the test runner's module-reset feature when available. This helper reloads the full synchronous dependency graph and repeats initialization side effects.

Keep a native addon outside the fresh graph protect-native-addon

const nativeBinding = require('./build/Release/addon.node');

const freshWrapper = stealthyRequire(
  require.cache,
  () => require('./wrapper'),
  () => require('./build/Release/addon.node'),
  module,
);

The implementation never deletes `.node` cache entries. The JavaScript wrapper may be fresh while the native binding remains shared.

Use a child process for stronger isolation isolate-in-child-process

const { fork } = require('node:child_process');

const child = fork(require.resolve('./load-plugin-child'), [pluginPath], {
  stdio: 'inherit',
});
child.on('exit', (code) => {
  if (code !== 0) process.exitCode = code;
});

A new process starts with clean loader state and contains native modules, globals, timers, and load errors more reliably than cache edits.

Pass Browserify's legacy cache argument browserify-cache-legacy

const fresh = stealthyRequire(arguments[5], () => {
  return require('./feature');
});

The README documents `arguments[5]` for Browserify 13.0.1. Generated wrapper arguments are not a portable current bundler API.

Alternatives

PackageRegistryPick it when
clear-modulenpmUse it to evict one named CommonJS module and its descendants rather than snapshotting nearly the whole cache.
import-freshnpmUse it for a narrower fresh CommonJS load in configuration scripts or tests.
decachenpmUse it when legacy code only needs to remove a selected module and child entries from the CommonJS cache.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.