JavaScript Cheatsheet
Modules
Use this JavaScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
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>