BBV logo

Part 1 - Javascript module types (CJS, AMD, UMD, ESM, WTF?)

Matias Mendoza

13 April, 2020 - 3 min read

Imagine having all your Javascript code messed in just one giant file. Reading thousands of lines trying to find that typo that is making your app not compile doesn't sound like a good plan.

Thanks God (or whatever), Javascript acquired simple ways of implementing modularity with all the benefits that importing and exporting bunches of code implies.

Nowadays, in terms of modularity, most popular patterns are CJS, AMD, UMD and ESM and the goal of this post is covering each of them at a high-level so you could make choose the one that meets your needs better while building your library.

CJS - CommonJS (2009)

  • Imports modules: Synchronously.
  • Main Target: Backend.

Syntax

Look an example here !

Summary

  • There are two entities:
  • require: provide the ability to load a module.
  • module: provide the ability to export a module interface to your library.
  • NodeJS uses CJS modularity pattern!
  • You can import your lib both...
  • from node_modules: const myLib = require(‘myLib’)
  • from a local dir: const myLocalLib = require('./path/to/file.js')
  • The imported result is a copy of the imported object.
  • More info here!

AMD - Asynchronous Module Definition (2009)

  • Imports modules: Asynchronously.
  • Main Target: Frontend

Syntax

Look an example here !

Summary

  • There is a function define that declares a module.
  • The first argument, id, is a string literal. It specifies the id of the module being defined.
  • The second one is an array of dependencies.
  • The last argument is the function with the code of the module that will be launched only after all dependencies of this module will be loaded.
  • More info here!

UMD - Universal Module Definition (2011)

  • Import modules: It depends on the implementation.
  • Main Target: Frontend and Backend (“Universal”).

Syntax

Look an example here !

Summary

  • It's more like an interface for bringing compatibility in Frontend and Backend environments to both AMD and CJS.
  • Nowadays, UMD is used by most developers when they need to bring support both in the browser or in NodeJS.
  • More info here!

ESM - ECMAScript Modules (2015)

  • Imports modules: Asynchronously.
  • Main Target: Frontend and Backend.

Syntax

Look an example here !

Summary

  • There are two new keywords import and export which explains by itself IMO.
  • Works in many modern browsers
  • Tree-shaking support due to ES6's static module structure
  • More info here!

To sum up…

Since it depends a lot on your needs, ESM looks like the best modularity pattern option thanks to its simple syntax, multiple platforms support and asynchronously and tree-shaking abilities.

UMD works also in all platforms and is usually used as a fallback in case ESM does not meet your needs. Many popular libraries support this format for example moment.js and lodash.

In case you need detailed information, there is an amazing article with the whole history of javascript modularity on Github.

Thanks a lot for reading! Remember this post is part of “From Zero to Hero: Painless way of building a great Javascript library” series.

See you next time at: “Part 2 - Semantic versioning. Releases at a glance.” !

Matias Mendoza

Co-Founder & COO

Subscribe for latest updates

Sign Up for our newsletter and get notified when we publish new articles for free!

Maybe you could be interested to read