Skip to main content
The node:module API provides utilities for working with modules and customizing module resolution and loading.

Import Module API

// ES modules
import { builtinModules, createRequire } from 'node:module';

// CommonJS
const { builtinModules, createRequire } = require('node:module');

module.builtinModules

List of all built-in Node.js modules:
import { builtinModules } from 'node:module';

console.log(builtinModules);
// ['fs', 'path', 'http', 'https', 'crypto', ...]

// Check if a module is built-in
const isBuiltin = builtinModules.includes('fs'); // true

module.createRequire()

Create a require function from ES modules:
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);

// Now you can use require() in ES modules
const pkg = require('./package.json');
const legacy = require('./legacy-commonjs-module');

Use Cases

// Load JSON files
const config = require('./config.json');

// Load CommonJS-only packages
const oldPackage = require('old-commonjs-package');

// Load native addons
const addon = require('./build/Release/addon.node');

module.isBuiltin()

Check if a module is a built-in Node.js module:
import { isBuiltin } from 'node:module';

console.log(isBuiltin('fs')); // true
console.log(isBuiltin('node:fs')); // true
console.log(isBuiltin('express')); // false

Module Compile Cache

The compile cache speeds up module loading by caching compiled code.

module.enableCompileCache()

Enable the compile cache:
import { enableCompileCache } from 'node:module';

const result = enableCompileCache();
console.log(result);
// {
//   status: 'ENABLED',
//   directory: '/tmp/node-compile-cache'
// }

With Custom Directory

const result = enableCompileCache({
  directory: '/path/to/cache',
  portable: true // Enable portable cache
});

Status Constants

import { constants } from 'node:module';

const { compileCacheStatus } = constants;

// compileCacheStatus.ENABLED - Cache enabled successfully
// compileCacheStatus.ALREADY_ENABLED - Already enabled
// compileCacheStatus.FAILED - Failed to enable
// compileCacheStatus.DISABLED - Disabled via NODE_DISABLE_COMPILE_CACHE

module.flushCompileCache()

Flush cached compilation data to disk:
import { flushCompileCache } from 'node:module';

// Write accumulated cache to disk
flushCompileCache();

module.getCompileCacheDir()

Get the compile cache directory:
import { getCompileCacheDir } from 'node:module';

const cacheDir = getCompileCacheDir();
console.log(cacheDir); // '/tmp/node-compile-cache' or undefined

Module Customization Hooks

Customize how Node.js resolves and loads modules.

Synchronous Hooks

Register synchronous hooks with registerHooks():
import { registerHooks } from 'node:module';

const hooks = registerHooks({
  resolve(specifier, context, nextResolve) {
    console.log('Resolving:', specifier);
    return nextResolve(specifier, context);
  },
  load(url, context, nextLoad) {
    console.log('Loading:', url);
    return nextLoad(url, context);
  }
});

// Later, deregister the hooks
hooks.deregister();

Resolve Hook

Customize module resolution:
registerHooks({
  resolve(specifier, context, nextResolve) {
    // Redirect imports
    if (specifier === 'old-package') {
      return nextResolve('new-package', context);
    }
    
    // Add custom conditions
    if (specifier.includes('dev')) {
      return nextResolve(specifier, {
        ...context,
        conditions: [...context.conditions, 'development']
      });
    }
    
    // Custom resolution
    if (specifier === 'virtual-module') {
      return {
        url: 'file:///virtual/module.js',
        format: 'module',
        shortCircuit: true
      };
    }
    
    return nextResolve(specifier, context);
  }
});

Load Hook

Customize module loading and source code:
registerHooks({
  load(url, context, nextLoad) {
    // Inject code
    if (url.endsWith('config.js')) {
      return {
        source: 'export const config = { env: "production" };',
        format: 'module',
        shortCircuit: true
      };
    }
    
    // Transform source code
    const result = nextLoad(url, context);
    if (typeof result.source === 'string') {
      return {
        ...result,
        source: result.source.replace(/DEBUG/g, 'false')
      };
    }
    
    return result;
  }
});

Supported Formats

FormatDescriptionSource Types
'module'ES modulestring, ArrayBuffer, TypedArray
'commonjs'CommonJS modulestring, ArrayBuffer, TypedArray
'json'JSON filestring, ArrayBuffer, TypedArray
'builtin'Node.js built-innull
'addon'Native addonnull
'wasm'WebAssemblyArrayBuffer, TypedArray

Deregistering Hooks

const hooks = registerHooks({
  resolve(specifier, context, nextResolve) {
    return nextResolve(specifier, context);
  }
});

// Remove hooks when done
hooks.deregister();

TypeScript Support

module.stripTypeScriptTypes()

Strip TypeScript type annotations:
import { stripTypeScriptTypes } from 'node:module';

const code = 'const x: number = 42;';
const stripped = stripTypeScriptTypes(code);

console.log(stripped);
// 'const x         = 42;'

With Source URL

const stripped = stripTypeScriptTypes(code, {
  mode: 'strip',
  sourceUrl: 'file.ts'
});

console.log(stripped);
// 'const x         = 42;\n\n//# sourceURL=file.ts'
This only strips type annotations. TypeScript features like enum require transformation.

module.findPackageJSON()

Find the package.json for a specifier:
import { findPackageJSON } from 'node:module';

// Find package.json for a package
const pkgPath = findPackageJSON('express', import.meta.url);
console.log(pkgPath);
// '/path/to/node_modules/express/package.json'

// Find nearest package.json for a relative path
const nearestPkg = findPackageJSON('..', import.meta.url);
console.log(nearestPkg);
// '/path/to/package.json'

module.register()

Register asynchronous module hooks (advanced):
import { register } from 'node:module';

// Register a hooks module
register('./my-hooks.mjs', import.meta.url);

Hooks Module

// my-hooks.mjs
export async function resolve(specifier, context, nextResolve) {
  // Async resolution logic
  return nextResolve(specifier, context);
}

export async function load(url, context, nextLoad) {
  // Async loading logic
  return nextLoad(url, context);
}
Asynchronous hooks run on a separate thread and have several limitations. Use synchronous hooks via registerHooks() when possible.

module.syncBuiltinESMExports()

Sync built-in ES module exports with modified CommonJS exports:
import { syncBuiltinESMExports } from 'node:module';
import fs, { readFile } from 'node:fs';

const originalReadFile = readFile;

// Modify CommonJS export
require('fs').readFile = customReadFile;

// Sync changes to ES module
syncBuiltinESMExports();

import('node:fs').then((esmFS) => {
  console.log(esmFS.readFile === customReadFile); // true
});

Environment Variables

NODE_COMPILE_CACHE

Set the compile cache directory:
# Enable compile cache with custom directory
export NODE_COMPILE_CACHE=/path/to/cache
node app.js

NODE_DISABLE_COMPILE_CACHE

Disable compile cache:
export NODE_DISABLE_COMPILE_CACHE=1
node app.js

NODE_COMPILE_CACHE_PORTABLE

Enable portable compile cache:
export NODE_COMPILE_CACHE_PORTABLE=1
node app.js

Examples

Custom Module Loader for CSS

import { registerHooks } from 'node:module';

registerHooks({
  load(url, context, nextLoad) {
    if (url.endsWith('.css')) {
      const source = `
        const styles = \`${fs.readFileSync(new URL(url), 'utf-8')}\`;
        export default styles;
      `;
      return {
        format: 'module',
        source,
        shortCircuit: true
      };
    }
    return nextLoad(url, context);
  }
});

// Now you can import CSS
import styles from './app.css';
console.log(styles); // CSS content as string

Package Alias

registerHooks({
  resolve(specifier, context, nextResolve) {
    // Alias old package to new package
    const aliases = {
      'old-package': 'new-package',
      'deprecated-lib': 'modern-lib'
    };
    
    if (specifier in aliases) {
      return nextResolve(aliases[specifier], context);
    }
    
    return nextResolve(specifier, context);
  }
});

Development Mode Injection

registerHooks({
  load(url, context, nextLoad) {
    const result = nextLoad(url, context);
    
    if (process.env.NODE_ENV === 'development') {
      const source = String(result.source);
      return {
        ...result,
        source: `
          console.log('Loading:', ${JSON.stringify(url)});
          ${source}
        `
      };
    }
    
    return result;
  }
});

ES Modules

ES module syntax and features

CommonJS

CommonJS module system

Packages

Package configuration and exports