JavaScript module formats

When you write modular JavaScript applications, you usually end up using one of following formats

In the old day, modules in JavaScript were implemented via libraries like CommonJS Modules (CJS), Asynchronous Module Definition (AMD), and Universal Module Definition (UMD). Since ES2015, JavaScript had built-in modules called ECMAScript Modules (ESM).

Besides the above popular JavaScript modules, we also consider other JavaScript module formats like System.register or global; and non-JavaScript modules like JSON modules, CSS modules, or Web Assembly.

ECMAScript Modules


ECMAScript modules are the official standard format to package JavaScript code for reuse. Modules are defined using a variety of import and export statements.



The Asynchronous Module Definition (AMD) API specifies a mechanism for defining modules such that the module and its dependencies can be asynchronously loaded. AMD provides some CommonJS interoperability. It allows for using a similar exports and require() interface in the code, although its own define() interface is more basal and preferred.



CommonJS's module specification is widely especially with Node.js, can be recognized by the use of the require() function and module.exports.



The Universal Module Definition (UMD) pattern typically attempts to offer compatibility with the most popular script loaders of the day (e.g RequireJS amongst others). In many cases it uses AMD as a base, with special-casing added to handle CommonJS compatibility.



System.register can be considered as a new module format designed to support the exact semantics of ES6 modules within ES5. This format provides support for dynamic import(), top-level await, live bindings updates, etc.