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
| Feature | ESM | CJS |
|---|---|---|
| Syntax | import/export | require/module.exports |
| Load time | static (compile-time) | dynamic (runtime) |
| Async | yes (top-level await) | no |
this at top level | undefined | module.exports |
__filename / __dirname | not available* | available |
| File extension | .mjs or .js (in ESM package) | .cjs or .js |
| Tree-shakeable | yes | no |
*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>