All skills
Skillintermediate

Module Systems

```javascript // Named exports export const PI = 3.14159; export function add(a, b) { return a + b; }

Claude Code Knowledge Pack7/10/2026

Overview

Module Systems

ES Modules (ESM)

// Named exports

  return a + b;
}

  multiply(a, b) {
    return a * b;
  }
}

// Default export

  async connect() {
    // implementation
  }
}

// Re-exports

Import Patterns

// Named imports

// Default import

// Namespace import

math.add(1, 2);

// Mixed imports

// Side-effect only import

// Type-only imports (for documentation)
/** @typedef {import('./types.js').User} User */

Dynamic Imports

// Basic dynamic import
const module = await import('./module.js');
module.default();

// Conditional loading
const loadFeature = async (feature) => {
  if (feature === 'advanced') {
    const { AdvancedFeature } = await import('./advanced.js');
    return new AdvancedFeature();
  }
  const { BasicFeature } = await import('./basic.js');
  return new BasicFeature();
};

// Code splitting by route
const router = {
  '/home': () => import('./pages/home.js'),
  '/about': () => import('./pages/about.js'),
  '/profile': () => import('./pages/profile.js')
};

const loadPage = async (route) => {
  const module = await router[route]();
  return module.default;
};

// Lazy loading with caching
const moduleCache = new Map();

const importWithCache = async (path) => {
  if (moduleCache.has(path)) {
    return moduleCache.get(path);
  }
  const module = await import(path);
  moduleCache.set(path, module);
  return module;
};

Package.json Configuration

{
  "name": "my-package",
  "version": "1.0.0",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    },
    "./utils": {
      "import": "./dist/utils.mjs",
      "require": "./dist/utils.cjs"
    },
    "./package.json": "./package.json"
  },
  "imports": {
    "#utils": "./src/utils/index.js",
    "#constants": "./src/constants.js"
  }
}

Conditional Exports

// package.json with conditional exports
{
  "exports": {
    ".": {
      "node": "./dist/node.js",
      "browser": "./dist/browser.js",
      "default": "./dist/index.js"
    },
    "./feature": {
      "development": "./src/feature.dev.js",
      "production": "./dist/feature.prod.js"
    }
  }
}

// Usage in code
import api from 'my-package'; // Resolves based on environment
import feature from 'my-package/feature'; // Conditional based on NODE_ENV

Import Maps (Browser)


<script type="importmap">
{
  "imports": {
    "lodash": "/node_modules/lodash-es/lodash.js",
    "react": "https://esm.sh/react@18",
    "utils/": "/src/utils/"
  }
}
</script>

<script type="module">

</script>

CommonJS Compatibility

// ESM consuming CommonJS

import { named } from './commonjs-module.cjs'; // May not work

// Use createRequire for CommonJS in ESM

const require = createRequire(import.meta.url);
const cjsModule = require('./commonjs-module.cjs');

// Access CommonJS metadata in ESM

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

Module Resolution

// Explicit file extensions required in ESM
import utils from './utils.js'; // Correct
import utils from './utils';    // Error in ESM

// Directory imports require index.js

// Using import.meta
console.log(import.meta.url); // file:///path/to/module.js
console.log(import.meta.resolve('./other.js')); // Resolve relative path

// Detect if module is main
if (import.meta.url === `file://${process.argv[1]}`) {
  // This module was run directly
  main();
}

Circular Dependencies

// moduleA.js

  return b;
}

// moduleB.js

  return a; // Works because 'a' is hoisted
}

// Best practice: avoid circular deps, use dependency injection
// factory.js

  return {
    name: 'A',
    useB: () => dependencies.b
  };
}

  return {
    name: 'B',
    useA: () => dependencies.a
  };
}

// index.js
const a = createA({});
const b = createB({});
a.dependencies = { b };
b.dependencies = { a };

Tree Shaking Optimization

// Write side-effect-free code for tree shaking
// utils.js - Good: pure functions

// Only used functions will be bundled
import { add } from './utils.js'; // Only 'add' bundled

// Bad: side effects prevent tree shaking
console.log('Module loaded'); // Side effect

// Mark as side-effect-free in package.json
{
  "sideEffects": false,
  // OR specify files with side effects
  "sideEffects": ["*.css", "polyfills.js"]
}

Module Patterns

// Singleton pattern
// database.js
class Database {
  #connection = null;

  async connect() {
    if (!this.#connection) {
      this.#connection = await createConnection();
    }
    return this.#connection;
  }
}

// Factory pattern
// loggerFactory.js

  return {
    info: (msg) => level !== 'silent' && console.log(msg),
    error: (msg) => console.error(msg)
  };
}

// Facade pattern
// api.js

  async getUser(id) {
    const cached = cache.get(`user:${id}`);
    if (cached) return cached;

    const token = await auth.getToken();
    const user = await get(`/users/${id}`, { token });
    cache.set(`user:${id}`, user);
    return user;
  }
};

Node.js ESM Specifics

// package.json
{
  "type": "module" // All .js files are ESM
}

// Use .cjs for CommonJS files when type: "module"
// Use .mjs for ESM files when type: "commonjs" (default)

// Loading JSON in ESM

// OR using fs

const data = JSON.parse(
  await readFile('./data.json', 'utf-8')
);

// Top-level await in Node.js ESM
const config = await fetch('/api/config').then(r => r.json());

Quick Reference

FeatureESMCommonJS
Syntaximport/exportrequire()/module.exports
LoadingAsynchronousSynchronous
Tree shakingYesNo
Top-level awaitYesNo
Dynamic importsawait import()require()
File extensionRequiredOptional
__dirnameUse import.meta.urlBuilt-in
Browser supportNativeNeeds bundler
Default mode"type": "module"No type field