CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-esm

ECMAScript module loader that enables ES module syntax in Node.js 6+ without Babel or bundling

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

ESM

ESM is the world's most advanced ECMAScript module loader. This fast, production-ready, zero-dependency loader enables ES module syntax in Node.js 6+ without requiring Babel or bundling. It provides seamless interoperability between CommonJS and ES modules with extensive configuration options.

Package Information

  • Package Name: esm
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install esm
  • Repository: https://github.com/standard-things/esm

Core Imports

// Main import
const esm = require("esm");

// Create enhanced require function
require = require("esm")(module);

// With options
require = require("esm")(module, options);

Basic Usage

// Method 1: Package-level setup (recommended)
// index.js
require = require("esm")(module)
module.exports = require("./main.js")

// main.js - now supports ES module syntax
import { readFile } from "fs";
import path from "path";
export const myFunction = () => "Hello ES modules!";

// Method 2: CLI usage
// node -r esm main.js

// Method 3: REPL usage
// node -r esm

Architecture

ESM works by providing an enhanced require function that can load both CommonJS and ES modules:

  • Module Loader: Patches Node.js module system to understand ES syntax
  • Parser Integration: Uses Acorn parser to detect ES module syntax
  • Live Bindings: Maintains proper ES module live binding semantics
  • Compatibility Layer: Provides seamless interoperability between module systems
  • Caching System: Integrates with Node.js module cache for performance
  • Hook System: Installs hooks for module, require, vm, and process objects

Capabilities

Main Loader Function

Creates an enhanced require function with ES module support.

/**
 * Create an enhanced require function with ES module support
 * @param {Object} module - The CommonJS module object (usually `module`)
 * @param {ESMOptions|string} [options] - Configuration options or mode string
 * @returns {Function} Enhanced require function with ES module loading capabilities
 */
function esmLoader(module, options);

Usage Examples:

// Basic usage
require = require("esm")(module);

// With string mode
require = require("esm")(module, "auto");

// With configuration object
require = require("esm")(module, {
  mode: "auto",
  cjs: true,
  await: false
});

// Now load ES modules
const myModule = require("./es-module.js");

Configuration Options

Complete configuration object for customizing loader behavior.

/**
 * ESM loader configuration options
 */
interface ESMOptions {
  /** CJS interoperability settings */
  cjs?: boolean | CJSOptions;
  /** Package.json fields to check when importing */
  mainFields?: string[];
  /** Module detection mode */
  mode?: "auto" | "all" | "strict";
  /** Enable top-level await support (Node 10+) */
  await?: boolean;
  /** Apply options to all module loads */
  force?: boolean;
  /** Enable WebAssembly module support (Node 8+) */
  wasm?: boolean;
  /** Cache directory path or toggle */
  cache?: boolean | string;
  /** Include inline source maps */
  sourceMap?: boolean;
}

/**
 * CommonJS interoperability configuration
 */
interface CJSOptions {
  /** Store ES modules in require.cache */
  cache?: boolean;
  /** Remove dangling .default access */
  dedefault?: boolean;
  /** Enable __esModule interoperability */
  esModule?: boolean;
  /** Respect require.extensions in ESM */
  extensions?: boolean;
  /** Enable mutable namespace objects */
  mutableNamespace?: boolean;
  /** Import named exports of CJS modules */
  namedExports?: boolean;
  /** Follow CJS path rules in ESM */
  paths?: boolean;
  /** Enable top-level return support */
  topLevelReturn?: boolean;
  /** Provide __dirname, __filename, require in ESM */
  vars?: boolean;
}

Configuration Examples:

// Auto mode with full CJS compatibility (recommended)
require = require("esm")(module, {
  mode: "auto",
  cjs: true
});

// Custom CJS interop settings
require = require("esm")(module, {
  mode: "auto",
  cjs: {
    cache: true,
    namedExports: true,
    vars: true,
    esModule: false
  }
});

// All files as ES modules
require = require("esm")(module, {
  mode: "all",
  force: true
});

Mode Configuration

Module detection and processing modes.

/**
 * Module detection modes
 */
type ModuleMode = "auto" | "all" | "strict";

/**
 * - "strict": Only .mjs files are treated as ES modules
 * - "auto": Detect ES modules by syntax (import/export/import.meta/"use module") or .mjs extension  
 * - "all": All files except those with "use script" directive or .cjs extension are ES modules
 */

Mode Examples:

// Strict mode - only .mjs files
require = require("esm")(module, "strict");

// Auto mode - detect by syntax
require = require("esm")(module, "auto");

// All mode - assume ES modules
require = require("esm")(module, "all");

Environment Configuration

External configuration through environment variables and config files.

/**
 * Environment configuration options
 */
interface EnvironmentConfig {
  /** ESM_OPTIONS: JSON6 configuration string or config file path */
  ESM_OPTIONS?: string;
  /** ESM_DISABLE_CACHE: Disable caching when truthy */
  ESM_DISABLE_CACHE?: string;
}

Environment Examples:

# JSON6 configuration
export ESM_OPTIONS='{"mode":"auto","cjs":true}'

# Config file path
export ESM_OPTIONS="./config/esm-config.json"

# Disable caching
export ESM_DISABLE_CACHE=true

# Then run
node -r esm main.js

Config file formats:

// .esmrc.js
module.exports = {
  mode: "auto",
  cjs: true
};

// .esmrc.json
{
  "mode": "auto", 
  "cjs": true
}

// package.json
{
  "esm": {
    "mode": "auto",
    "cjs": true
  }
}

Advanced Features

Enhanced capabilities and integrations.

/**
 * Advanced feature flags
 */
interface AdvancedFeatures {
  /** Top-level await support (Node 10+) */
  await?: boolean;
  /** WebAssembly module support (Node 8+) */
  wasm?: boolean;
  /** Force options on all loads */
  force?: boolean;
  /** Source map generation */
  sourceMap?: boolean;
}

Advanced Examples:

// Enable top-level await
require = require("esm")(module, {
  mode: "auto",
  await: true,
  cjs: true
});

// WebAssembly support
require = require("esm")(module, {
  mode: "auto",
  wasm: true
});

// Force all modules through ESM
require = require("esm")(module, {
  mode: "auto",
  force: true,
  sourceMap: true
});

Error Handling

ESM throws standard Node.js module errors and includes specific validation:

// Invalid module parameter
try {
  require("esm")("not-a-module");
} catch (error) {
  // ERR_INVALID_ARG_TYPE: The "module" argument must be of type object
}

// Module syntax errors are reported normally
try {
  require("./invalid-syntax.js");
} catch (error) {
  // SyntaxError with file location and details
}

Integration Patterns

Testing Frameworks

// Jest
require = require("esm")(module);

// Mocha
// mocha --require esm test/**/*.js

// AVA
// ava --require esm test/**/*.js

Development Tools

// Webpack
module.exports = {
  resolve: {
    mainFields: ["module", "main"]
  }
};

// Package.json for bundlers
{
  "main": "index.js",
  "module": "main.js"
}

Supported Features

  • ✅ ES Module import/export statements
  • ✅ Dynamic import() expressions
  • import.meta object support
  • ✅ Live bindings between modules
  • ✅ File URI scheme support
  • ✅ Node.js CLI integration (--eval, --print, --check)
  • ✅ REPL support
  • ✅ Full CommonJS interoperability
  • ✅ WebAssembly module loading (Node 8+)
  • ✅ Top-level await (Node 10+)
  • ✅ Source map support
  • ✅ Yarn PnP integration
  • ✅ Multiple configuration sources
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/esm@3.2.x
Publish Source
CLI
Badge
tessl/npm-esm badge