NODEJS Contents

ES Modules in Node (import/export, package.json type)

Learn how ES Modules work in Node.js, how to configure them correctly, and how to avoid the most common ESM pitfalls in real-world backend projects.

On this page

What Are ES Modules?

ES Modules (ESM) are the official JavaScript module standard. They use import and export syntax and are supported by modern browsers and Node.js.

Basic Syntax

// math.js
export function add(a, b) {
  return a + b;
}

// index.js
import { add } from './math.js';
console.log(add(2, 3));

Enabling ESM in Node

Node requires explicit configuration to treat files as ES Modules.

Option 1: package.json

{
  "type": "module"
}

This tells Node that .js files are ES Modules.

Option 2: .mjs Extension

Files with .mjs are treated as ES Modules regardless of package.json.

File Extensions Are Required

Unlike CommonJS, ESM requires explicit file extensions:

import { add } from './math.js'; // correct
import { add } from './math';    // error in Node ESM

__dirname Is Not Available

ESM does not provide __dirname or __filename automatically.

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

Top-Level await

ES Modules allow top-level await:

const data = await fetchData();
console.log(data);

Interoperability with CommonJS

Importing CommonJS modules in ESM is supported, but named exports may not behave as expected.

Production Pitfalls

  • Forgetting file extensions.
  • Mixing CJS and ESM incorrectly.
  • Tooling mismatches (TypeScript config vs Node runtime).

TypeScript Configuration

When using TypeScript, set:

{
  "compilerOptions": {
    "module": "NodeNext",
    "moduleResolution": "NodeNext"
  }
}

When to Choose ESM

  • New projects
  • Modern tooling
  • Browser + Node shared libraries

When to Be Careful

  • Legacy ecosystems
  • Older deployment environments

Production Insight

Choose one module system per project. Mixing strategies without understanding resolution rules creates subtle runtime bugs.

Next Step

Next we will cover CommonJS (CJS) to understand how legacy and modern systems interact.