Introduction

In the previous chapter, we briefly introduced the importance of modules in Node.js. We discussed how modules play a fundamental role in defining some of the pillars of the Node.js philosophy and its programming experience. But what do we actually mean when we talk about modules and why are they so important?

In generic terms, modules are the bricks for structuring non-trivial applications. Modules allow us to divide the codebase into small units that can be developed and tested independently. Modules are also the main mechanism to enforce information hiding by keeping private all the functions and variables that are not explicitly marked to be exported.

If you come from other languages, you have probably seen similar concepts being referred to with different names: package (Java, Go, PHP, Rust, or Dart), assembly (.NET), library (Ruby), or unit (Pascal dialects). The terminology is not perfectly interchangeable because every language or ecosystem comes with its own unique characteristics, but there’s a significant overlap between these concepts.

Interestingly enough, Node.js currently comes with two different module systems: CommonJS (CJS) and ECMAScript modules (ESM or ES modules). In this chapter, we’ll discuss why there are two alternatives, we’ll learn about their pros and cons, and, finally, we’ll analyze several common patterns that are relevant when using or writing Node.js modules. By the end of this chapter, you should be able to make pragmatic choices about how to use modules effectively and how to write your own custom modules.

Getting a good grasp of Node.js’ module systems and module patterns is very important because we’ll rely on this knowledge in all the other chapters of this course.

Get hands-on with 1200+ tech skills courses.