What is the difference betwen .mjs vs .cjs vs .js (Are these used in JavaScript or in node?)
Hello, can someone explain what is the difference between the file extensions used in node/js,
.mjs
, .cjs
and .js
please. I always sticked to .js
so is there any use case of the other file extensions? I know that .mjs
stands for module javascript or something like that, so naming a file as .js
means we don't necessarily need to modify our package.json
to include type as module
?
What about .cjs
please, I just know it stands for common javascript.
Do the import and export statement differs between these extensions?
Why do we have 3 type of extensions? Does the compiler or interpreter or whatever run the code interpret the scripts differently based on the extensions?10 Replies
*
.js
is a vanilla JS file. Nothing special
* .mjs
is a JS module file
* .cjs
is specific to Node.js and uses the outdated CommonJS require
syntax
What does this mean? Well, due to backwards compatibility requirements all .js
files are expected to be JavaScript files, not modules and not commonjs modules. That means you need to tell the browser that you're importing a module (<script type="module">
) or Node js that you're using module type importing (type: module
).
If you use .mjs
the broser/Node knows it's a module and will do all the module-type stuff for you. Also, JS modules are automatically run in strict mode so you don't have to type "use strict";
at the top of all JS files you write.
Do the import and export statement differs between these extensions?Yes, modules use the
import
and export
syntax. JS files rely on you loading each JS file in the correct order in the browser (using script
tags). CJS uses module.exports
and require
to import/export modules.
Why do we have 3 type of extensions?Because of progress. When JS first came about there wasn't a need for modules b/c the scripts were tiny and simple. But as JS grew there needed to be a way to do. There was no standard way to import/export code from one file to another. In 2009 Nodejs needed a way to do this, so they made CJS. Fast forward 6 years and ES2015 came out with the ESM standard. And that's what every JS runtime uses now, even if (like Nodejs) they also allow for non-ESM systems. Remember that the promise of web tech is backward compatibility. Something written in 1998 needs to run now just like it did back then. So you can't just remove parts of the JS, that would literally break the web! Instead, we have non-versioned ways of doing things.
Does the compiler or interpreter or whatever run the code interpret the scripts differently based on the extensions?Yes. See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
Yep I see, it's lot clearer now, thanks !
One question though
hmm I don't think I have use import statement or
.mjs
file extension for JavaScript yet, like scripts that browser run. I did it on node though, I should try on the browser but say I have script 1 and script 2.
Basically say script 2 is a module we want to import. We must explicitly use .mjs
for the browser? (Like in node, the type: module means the JS are interpreted as a module)
say script 2 was imported, should we have a script tag for it as well in our HTML?either
script2.mjs
or <script type="module" src="script2.js">
No, that's what modules are made to preventwhen we say something is a module, like
<script type="module" src="script2.js">
, what that mean is:
Treat this as a module (a module is just a piece of code that can be imported/export so that we don't have to repeat ourself again an again right?), so we can import things in it and export things from it?Yes
Note that type field of package json isn't mandatory for node.
https://nodejs.org/api/packages.html#introduction_1

Though it will throw a warning in console if you don't specify type and try to run js file containing import export syntax
one thing is confusing me (it's more about syntax really but that's annoying me :c), say I have 2 scripts,
script1.js
and script2.js
.
My question is:
script2.js
is a module, I have written a function that we are going to import and call in script1.js
.
My question is in the script tag in our index.html
, should we mark module as type? If yes, why pls.
The thing is, for script1 why is it called a "module"? I mean normally, we don't run a module, we call it, no?Even if script1 is using only import it's still a module.
Modules is just a term for splitting code across multiple files. Your script1 falls into this too since it also just another file that contains part of the larger code
Also I don't understand what you mean by run vs call a module
"Module" means it can
import
and export
code for other scripts to use. It's modular code.
You need to do something to tell the browser that you're using modular script and not a non-modular script—either using the .mjs
extension or type="module"
for the script tag.
An error will be thrown if your–https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html<script>
element doesn't have thetype="module"
attribute and attempts to import other modules.