JavaScript Cheatsheet

Modules

Use this JavaScript reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

ES Modules (ESM)

ES Modules are the standard module system (import/export), supported natively in browsers and Node.js (.mjs or "type": "module" in package.json). Modules are strict mode by default, evaluated once, and statically analyzed.

Named Exports

// math.js
export const PI = 3.14159;
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }
export class Vector { /* ... */ }

// Batch export
const x = 1;
const y = 2;
export { x, y };

// Rename on export
export { add as sum, subtract as diff };

Default Export

// Only one default per file
export default function greet(name) {
  return `Hello, ${name}!`;
}

// Or:
const greet = name => `Hello, ${name}!`;
export default greet;

// Class default
export default class User { /* ... */ }

Named Imports

// Import specific exports
import { add, PI } from "./math.js";
add(1, 2); // 3

// Rename on import
import { add as sum, subtract as diff } from "./math.js";

// Import all as namespace
import * as math from "./math.js";
math.add(1, 2); // 3
math.PI;        // 3.14159

Default Import

import greet from "./greet.js";    // any name, no braces
greet("Alice"); // "Hello, Alice!"

// Combine default + named
import greet, { helper, CONSTANT } from "./module.js";

Re-Exporting

// Re-export named
export { add, subtract } from "./math.js";
export { default as greet } from "./greet.js";

// Re-export all
export * from "./math.js";
export * as math from "./math.js"; // namespace re-export

// Rename during re-export
export { add as sum } from "./math.js";

Dynamic Import

// import() returns a Promise — for lazy loading or conditional imports
const math = await import("./math.js");
math.add(1, 2);

// Named exports
const { add, PI } = await import("./math.js");

// Default export
const { default: greet } = await import("./greet.js");

// Conditional
if (process.env.NODE_ENV === "development") {
  const { devTools } = await import("./dev-tools.js");
  devTools.enable();
}

// In non-async context
import("./module.js")
  .then(module => module.doSomething())
  .catch(console.error);

CommonJS (CJS — Node.js)

CommonJS is the older Node.js module system. Not natively supported in browsers.

// Exporting
module.exports = { add, subtract };      // export object
module.exports = function greet() {};    // export single value
exports.add = function() {};             // named export shorthand
// Note: mixing module.exports and exports breaks exports

// Importing
const math = require("./math");          // relative path
const math2 = require("./math.js");     // extension optional
const path = require("path");            // built-in module
const express = require("express");      // npm package

// Destructure on require
const { add, subtract } = require("./math");

// Dynamic require
const name = "math";
const mod = require(`./${name}`);       // runtime path resolution

CJS vs ESM Key Differences

FeatureESMCJS
Syntaximport/exportrequire/module.exports
Load timestatic (compile-time)dynamic (runtime)
Asyncyes (top-level await)no
this at top levelundefinedmodule.exports
__filename / __dirnamenot available*available
File extension.mjs or .js (in ESM package).cjs or .js
Tree-shakeableyesno

*In ESM: import.meta.url, import.meta.dirname (Node 20.11+)

// ESM equivalents of __filename / __dirname
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Node 20.11+:
const __dirname = import.meta.dirname;

import.meta

import.meta.url       // URL of current module: "file:///path/to/file.js"
import.meta.dirname   // directory (Node 20.11+)
import.meta.filename  // file path (Node 20.11+)
import.meta.env       // environment vars in Vite/bundlers
import.meta.env.DEV   // true in development (Vite)
import.meta.resolve("lodash") // resolve module specifier to URL

Module Patterns

Barrel File (index.js)

// src/utils/index.js — re-export everything for clean imports
export { formatDate, parseDate } from "./dates.js";
export { sum, average, round } from "./math.js";
export { capitalize, truncate } from "./strings.js";

// Consumer
import { formatDate, sum } from "./utils/index.js";
// or:
import { formatDate, sum } from "./utils"; // bundlers resolve index

Module with Private State

// counter.js — encapsulate state
let count = 0;          // module-private

export function increment() { return ++count; }
export function decrement() { return --count; }
export function reset()     { count = 0; }
export const getCount = () => count;

Conditional Module (platform detection)

// detect.js
export const isBrowser = typeof window !== "undefined";
export const isNode = typeof process !== "undefined" && process.versions?.node;

// Lazy platform module
const storage = isBrowser
  ? await import("./browser-storage.js")
  : await import("./node-storage.js");

Tree Shaking

Tree shaking removes unused exports at bundle time. Only works with ESM static imports.

// GOOD — bundler can tree-shake (static analysis)
import { add } from "./math.js"; // subtract not imported → excluded from bundle

// BAD for tree-shaking — dynamic (bundler can't know what's used)
const { add } = require("./math"); // CJS — whole module included
const fn = await import(dynamicPath); // dynamic path — can't analyze

Circular Dependencies

// a.js
import { b } from "./b.js";
export const a = "a";
console.log(b); // may be undefined during init — circular

// b.js
import { a } from "./a.js";
export const b = "b";
console.log(a); // may be undefined during init — circular

// Solution: move shared code to a third module or use functions

Loading in HTML (Browser)

<!-- ES Module — deferred by default, not executed until DOM ready -->
<script type="module" src="app.js"></script>

<!-- Inline module -->
<script type="module">
  import { greet } from "./greet.js";
  greet("World");
</script>

<!-- Import map — browser-native bare specifier resolution -->
<script type="importmap">
{
  "imports": {
    "lodash": "https://cdn.jsdelivr.net/npm/lodash-es/lodash.js",
    "utils/": "./src/utils/"
  }
}
</script>
<script type="module">
  import { debounce } from "lodash";       // resolves via importmap
  import { formatDate } from "utils/dates.js";
</script>