ES Modules

JavaScript Module Systems: require, import, .mjs & More
JavaScript once had no built-in way to split code across files — a limitation that spawned an entire ecosystem of competing module formats. Today, developers encounter require(), import, .mjs, .cjs, AMD, and UMD, often all in the same project. This guide demystifies every module system, explains when to use each, and maps out the clear path forward. Why JavaScript Needed Module Systems In the early days of the web, JavaScript was a scripting language meant for simple page interactions. As applications grew, developers stuffed everything into global variables — leading to naming collisions and unmaintainable “spaghetti” code [1]. The community responded by inventing module patterns outside the language itself: first Immediately Invoked Function Expressions (IIFEs) to create private scopes, then formal module specifications like AMD and CommonJS. Only in 2015 did JavaScript finally gain a native module system via the ES6 specification [6].