Explain Codes LogoExplain Codes Logo

What is the difference between .js and .mjs files?

javascript
es-modules
commonjs
module-system
Anton ShumikhinbyAnton Shumikhin·Mar 11, 2025
TLDR

.js and .mjs files are designed for CommonJS and ECMAScript Modules (ESM), respectively.

.js files incorporate the traditional require/module.exports Node.js module system. Meanwhile, .mjs files denote the modern ESM import/export module system. ESM offers benefits such as static analysis and tree-shaking.

// A Jedi's powers flow from the CommonJS const lib = require('library'); // .js file usage // Use the force of ESM, Luke import lib from 'library.mjs'; // .mjs file usage

By setting "type": "module" in package.json, .js files can also be treated as ESM. This is an increasingly popular choice due to the ESM's wide compatibility and efficiency.

Key differences: CommonJS vs. ESM

Understanding the differences between CommonJS and ESM is paramount in today's JavaScript development sphere. The V8 engine behind Node.js has specific optimizations for .mjs, heightening the significance of .mjs over .js. These files provide an explicit signal that the code employs the ESM syntax.

Shifting between .js and .mjs

Node.js allows .js files to operate as ESM by specifying "type": "module" in package.json. However, this could introduce complications when importing CommonJS modules, necessitating modifications in the importing approach.

With web browsers having supported ES Modules natively since 2018, the same module system can be applied for both client-side and server-side development. This consistency greatly streamlines coding and deployment processes.

When shifting towards ESM, be aware of any substantial changes in code execution, like "temporal dead zones". Unlike CommonJS, ESM disallow access to imports before their definition, which may necessitate some adjustments in your coding style but inherently enforce better structuring and more predictable outcomes.

Transitioning to a modular future with .mjs files

Moving forward, Node.js is gravitating towards ES modules, with .mjs acting as a pathway to this modular future. Using .mjs aids in organizing your JavaScript codes. Additionally, it simplifies the process of maintaining and updating the Node.js projects by clearly indicating the utilized module system.

ES6 modules typically encourage the development of smaller and more reusable components. This benefits not only the testability and readability of your codes but also illustrates how adopting ESM could exemplify the embracement of software development's best practices.