Is CommonJS 'require' still used or deprecated?
Solution 1:
CommonJS will likely be supported in nodejs for a long time as there are still millions of lines of code written using it. It is the original module loading mechanism in nodejs. It is not deprecated.
ESM modules (ECMAScript modules) that use import
and export
are the new Javascript standard for modules and we can expect that nodejs will support these for as long as they are the Javascript standard (probably forever).
These two modules standards are not entirely compatible so mixing and matching within the same project can lead to complications that you have to learn how to deal with.
New Projects
If I were starting a new project today, I'd choose to write my code using ESM modules as it is the future trajectory of the language and nodejs. And, you can still load CommonJS modules into ESM modules if you require backward compatibility with other modules, but you do have to know how to do it properly - it's not always seamless to mix and match module types.
When ESM modules were first supported in nodejs, the interoperability with CommonJS modules was not very full featured and created some difficulties. As of the more recent versions of nodejs, you can load a CommonJS module from an ESM module or vice versa- you just have to use the right techniques to do it. This makes working from an ESM project a lot more feasible now than it was when ESM support in nodejs first came out as you can still access libraries in NPM that only support CommonJS.
Note also that more and more libraries in NPM are supporting direct loading from either module type so they are equally easy to use whether your project is CommonJS or ESM.
Over time, I would expect that any actively developed, shared module on NPM will eventually support direct loading as an ESM module. But, we're in this transition period of time where many have not yet implemented that or there are particular challenges in implementing the new loading scheme (which comes with it's own and different set of rules). In the meantime, you can still load CommonJS modules into ESM projects.
Existing CommonJS Projects
If I had an existing project that was CommonJS, I would not be spending any time thinking about converting it to ESM because there is still widespread support for CommonJS and my developer time is probably better spent on adding features, testing, fixing bugs, etc... than converting module formats.
Interoperability
One of the important interoperability things to know is that you can load a CommonJS module from an ESM module in several different ways:
- With a static import:
import { callMeCommon } from '../otherProject/common.js';
- With a dynamic import
import(someFile).then(...)
- By using
module.createRequire(import.meta.url)
and then using thatrequire()
function to load your CommonJS module.
You can also use the dynamic import('someModule').then(...)
to load an ESM module from a CommonJS module, but it's not synchronous like require()
was so it has to be dealt with differently.
It's also useful to know that ESM modules do not have some nodejs niceties that CommonJS modules had. There's no automatic __dirname
or __filename
to tell you exactly where this file was loaded from. Instead, you have to parse those values out of import.meta.url
and compute them. So, it's still possible to get that information, it's just not as convenient as it used to be.
On the other hand, ESM modules have some features like top level await
that CommonJS do not which can be very useful.
Your Specific Questions
So, is CommonJS 'require' something that is still used in projects?
Yes, it is still used a lot.
Or is it slowly dying and needed only for maintaining legacy codes?
I wouldn't so much say that it is dying as there are very few projects on NPM that don't still support CommonJS. In fact, when a project releases a new version that no longer supports CommonJS, it creates quite a problem for their user base (we see some of these issues here on stackoverflow) because of the significant prevalence of CommonJS projects still and people not familiar with how to load different module types.
So, I'd say that we're still in a very early stages of a transition from CommonJS to ESM and it's more like ESM is getting more and more adoption rather than CommonJS is dying. I'd hazard a guess that the majority of modules on NPM will, over the next few years, move to support direct loading from both module formats.
Transpiling
Lastly, developers often use transpiling to allow them to write code using the newest syntax and features, but using a transpiler to convert the code back to a lower, common denominator that runs anywhere. That can also be done for module architecture (write code in ESM, transpile to CommonJS).
A Few Interesting References
What does it take to support Node.js ESM?
Hybrid npm packages (ESM and CommonJS)
Node Modules at War: Why CommonJS and ES Modules Can’t Get Along
All you need to know to move from CommonJS to ECMAScript Modules (ESM) in Node.js