The basics
What is a JavaScript file?
A JavaScript file holds a program written in JavaScript, the only programming language every web browser runs. On a web page, HTML provides the content, CSS the look, and JavaScript the behaviour: menus that open, forms that check what you typed, maps you can drag, whole applications like webmail and online editors. The file is plain text, so you can open it in any text editor and read it.
JavaScript also runs outside the browser. Node.js, Deno and Bun run .js files directly on a computer or server, which is how much of the web's back-end code and many developer tools are written.
Three things that clear up common confusion:
- JavaScript is not Java. The name was a marketing decision in 1995. The two languages are unrelated in design and use.
- ECMAScript is the standard; JavaScript is the language. Ecma International publishes the language specification as ECMA-262, and browsers and Node.js implement it. "ES2015" or "ES6" names an edition of that standard.
- The language and the environment are separate. Variables, functions and classes are JavaScript.
document,windowandfetchcome from the browser;require,processand the file system come from Node.js. A file written for one often fails in the other.
Anatomy
What's inside a JavaScript file
A JavaScript file is a list of statements that run from top to bottom, plus functions that run later, when something calls them. Here is a short browser script that counts clicks on a button and asks a server for a total, part by part.
// Count clicks on a "like" button
"use strict";
const button = document.querySelector("#like");
let count = 0;
function label(n) {
return n === 1 ? "1 like" : `${n} likes`;
}
button.addEventListener("click", () => {
count += 1;
button.textContent = label(count);
});
async function loadTotal() {
const response = await fetch("/api/likes");
const data = await response.json();
console.log("Total likes:", data.total);
}
loadTotal().catch((error) => console.error(error));- 1
// Count clicks on a "like" buttonA comment
//comments run to the end of the line;/* … */comments can span several. Minifiers remove both. - 2
"use strict";Strict mode
Turns some silent mistakes into errors, such as assigning to a variable you never declared. It must be the first statement. ES modules are always strict, so they don't need it.
- 3
document.querySelector("#like")A browser API
documentisn't part of the JavaScript language: the browser provides it so scripts can read and change the page. Node.js has nodocument, which is why browser code fails there with "document is not defined". - 4
const button = … / let count = 0;Variables
constcan't be reassigned;letcan. Both exist only inside the block where they're declared. The oldervaris still valid but scoped to the whole function, which causes subtle bugs. - 5
function label(n) { … }A function
A named, reusable piece of code. Function declarations are hoisted: you can call them from lines above where they're written.
- 6
`${n} likes`A template literal
Backtick strings can insert values with
${…}and span several lines. Here it sits in a conditional expression:condition ? a : b. - 7
button.addEventListener("click", () => { … })An event listener
Browser JavaScript is mostly event-driven: this registers an arrow function to run every time the button is clicked, long after the rest of the file has finished.
- 8
async function loadTotal() { … }An async function
awaitpauses this function, and only this function, until the network answers. The rest of the page stays responsive in the meantime. - 9
await fetch("/api/likes")A network request
fetchasks a server for data, andresponse.json()parses the answer as JSON, the data format based on JavaScript's own object syntax. - 10
console.log("Total likes:", …)Console output
Prints to the browser's developer tools (the Console tab) or, in Node.js, to the terminal. Visitors never see it on the page.
- 11
.catch((error) => console.error(error))Error handling
If the request fails, the error is caught and logged here instead of surfacing as an unhandled promise rejection.
Under the hood
Classic scripts vs ES modules
The same .js file can be loaded in two different ways, and the rules change completely. A classic script is how JavaScript worked from the start. An ES module is the newer, standard way to split code into files that import from and export to each other, introduced in ES2015.
| Classic script | ES module | |
|---|---|---|
| Loaded with | <script src="app.js"> | <script type="module" src="app.js"> |
import and export | Syntax error | Yes |
| Strict mode | Only with "use strict" | Always |
| Top-level variables | Global, shared with every other script | Private to the module |
| When it runs | At once, pausing the HTML parser, unless defer or async is set | Deferred automatically, after the page is parsed |
Top-level await | Syntax error | Allowed |
Opened from file:// | Works | Blocked by the browser |
Wrong Content-Type from the server | Often still runs | Refused |
| Same file included twice | Runs twice | Runs once |
Why modules fail when you double-click the HTML file
Browsers fetch modules with the same security checks as cross-origin requests, and pages opened from file:// don't pass them. Test module-based pages through a local web server (for example npx serve or python3 -m http.server), or put them online.
Extensions
.js vs .mjs vs .cjs
Browsers don't care about the extension: a file is a module if the page loads it with type="module", and the server's Content-Type decides whether it's JavaScript at all. The extension matters to Node.js and build tools, which have to decide how to read a file before running it:
| Extension | In Node.js | Typical use |
|---|---|---|
.mjs | Always an ES module | Modules, in projects that mix both kinds |
.cjs | Always CommonJS (require and module.exports) | Old-style files inside an ES module project |
.js | Whatever the nearest package.json says in its "type" field; CommonJS if there's no "type", though current Node.js switches to module mode when it finds import or export in the file | Almost everything |
{
"name": "my-app",
"type": "module"
}With "type": "module", every .js file in the package is an ES module. Node.js's documentation recommends always setting the field, even to "commonjs", so tools don't have to guess. On the web, check that your server sends .mjs files as text/javascript: some older server configurations don't know the extension and send a generic type, which makes browsers refuse the module.
Serving it
The right MIME type and encoding
RFC 9239, published in 2022, made text/javascript the one recommended media type for JavaScript, for both .js and .mjs. It marks application/javascript, application/ecmascript, text/ecmascript and a few others as obsolete aliases. Browsers still accept them, but new server configurations should send text/javascript.
- Encoding: modules must be UTF-8. For classic scripts, a byte order mark or a
charsetin theContent-Typecan declare another encoding. Save every script as UTF-8 and you won't need either. X-Content-Type-Options: nosniffmakes browsers refuse any script, classic or module, that isn't served with a JavaScript type. It's a good security header, and the reason a misconfigured server can suddenly break every script on a site.- A 404 page is HTML. When a script's path is wrong, many servers answer with an HTML error page, and the browser reports a MIME type error rather than a missing file. Check the address first.
History
ECMAScript versions
| Edition | Year | Notable for |
|---|---|---|
| ES1 | 1997 | The first standard, based on Netscape's JavaScript |
| ES3 | 1999 | Regular expressions and try/catch; the baseline for a decade |
| ES5 | 2009 | Strict mode, JSON support, array methods like map and filter |
| ES2015 (ES6) | 2015 | The big update: let and const, classes, arrow functions, modules, promises, template literals |
| ES2016 onwards | Every June | Smaller yearly editions: async/await (2017), optional chaining ?. (2020) and more |
| ES2026 | June 2026 | The 17th edition: Error.isError(), Math.sumPrecise, Array.fromAsync, base64 and hex methods on Uint8Array |
A JavaScript file doesn't declare which edition it uses. What matters is whether the browsers or Node.js versions you support understand the syntax and functions in it. Build tools can rewrite newer syntax into older forms ("transpiling") when you need to support old browsers.
Troubleshooting
The JavaScript errors people hit most, and what they mean
| Error message | Usual cause | Fix |
|---|---|---|
| Cannot use import statement outside a module | A file with import was loaded as a classic script, or as CommonJS in Node.js | Add type="module" to the <script> tag; in Node.js use .mjs or "type": "module" |
| Failed to load module script: … MIME type of "text/html" | The path is wrong and the server sent an HTML error page, or .mjs isn't mapped to a JavaScript type | Fix the path; serve the file as text/javascript |
| Blocked by CORS policy, origin 'null' | A module page opened from file:// | Use a local web server or put the page online |
| require is not defined | CommonJS code running in a browser or in an ES module | Use import, or bundle the code |
| document is not defined | Browser code running in Node.js | Run it in a browser, or guard it with typeof document !== "undefined" |
| Cannot read properties of null | The script ran before the element it looks for existed | Add defer to the <script> tag or move it to the end of <body> |
Every browser has a Console (F12, or Option+Command+J in Chrome on a Mac) that shows these errors with the file and line number. It's the first place to look when a page "does nothing".
How to
How to open, run and edit a JavaScript file
- Read or edit it: open it in a code editor such as VS Code, or any plain-text editor. Opened in a browser on its own, a
.jsfile shows as text; it doesn't run. - Run it in a browser: load it from an HTML page with a
<script>tag, or paste short snippets into the developer tools' Console. - Run it on your computer: install Node.js and run
node file.jsin a terminal. Deno (deno run file.js) and Bun (bun file.js) work too. - Check the syntax without running it:
node --check file.jsreports syntax errors and exits. - Format, lint and minify: Prettier formats, ESLint finds likely bugs, and esbuild or Terser minify. Our HTML tester runs a page with inline JavaScript in a sandbox.
On Windows, don't double-click a .js file to "open" it: by default Windows runs it with Windows Script Host, outside the browser, as explained below.
Security
Is it safe to open a JavaScript file?
In a web page, JavaScript runs inside the browser's sandbox: it can't read your files or install programs. The danger is a .js file on its own:
- Windows runs
.jsfiles outside the browser. Double-clicking one starts Windows Script Host, which runs it as JScript with your user account's permissions: it can download and start other programs. Malicious.jsattachments, often inside ZIP files, have long been used to install malware this way, and many email services block.jsattachments for that reason. - Third-party scripts have full access to your page. A script loaded from someone else's server can read everything on the page, including what visitors type. Load only scripts you trust, and pin them with the
integrityattribute (Subresource Integrity) so a changed file is refused. - Packages are code too. An
npm installcan pull in hundreds of other people's files, and a compromised package runs with your permissions on your computer or server.
Never run a .js file you received unexpectedly. If you need to see what it does, open it in a text editor, which only shows the code.
Free downloads
Sample JavaScript files to download
Free sample JavaScript files for testing parsers, bundlers, minifiers, upload filters, MIME types and size limits. Each one passes node --check and runs without errors in Node.js and, except the CommonJS sample, in browsers.
Loading…What's inside sample-script.js
The file is commented: open it in a text editor and each numbered comment marks one of these parts. Run it with node sample-script.js to see its output.
Comments 1 and 2: strict mode and variables
"use strict"at the top, thenconstandlet, with a note on whyvaris best avoided.Comment 3: values
An object literal with a string, a number, a boolean, an array and
null: the syntax JSON is based on.Comments 4 and 5: functions and modern syntax
A function with a default parameter, an arrow function, a template literal, then destructuring with a rest element, optional chaining
?., the??operator and object spread.Comment 6: array methods
filter,mapandreducechained together: the doubled scores above 5 add up to 74.Comments 7 and 8: a class and error handling
A
Counterclass with a private#countfield, and atry/catcharoundJSON.parsethat returnsnullfor invalid input.Comment 9: asynchronous code
A promise-based
wait()and anasyncfunction that awaits it before printing.Comments 10 and 11: environment checks and output
The script only touches
documentwhen it exists, so the same file runs in a browser (where it sets an element withid="js-status"to "running") and in Node.js. Results go toconsole.log.
All sample JavaScript files
Commented sample script
sample-script.js · 3.1 KB (3,188 bytes)
A classic script covering variables, functions, destructuring, array methods, a class with a private field, error handling and async/await, with numbered comments explaining each part. Runs in browsers and Node.js.
- Checking parsers, linters and minifiers on modern syntax
- Teaching the building blocks of JavaScript
ES module (.mjs)
sample-module.mjs · 1.3 KB (1,303 bytes)
An ES module that imports named and default exports from
sample-module-math.mjs, uses top-levelawaitandimport.meta.url, and exports a value. Keep both files in the same folder.- Checking a server sends `.mjs` as `text/javascript`
- Testing module loading in browsers, Node.js and bundlers
Module that sample-module.mjs imports
sample-module-math.mjs · 612 bytes
A small module with only exports: a constant, two named functions and a default export.
- Testing import resolution
- A minimal ES module example
CommonJS module for Node.js
sample-commonjs.js · 836 bytes
Node.js's original module system:
require(),module.exports,__filenameand therequire.main === modulecheck. Runs withnode sample-commonjs.js; browsers can't run it.- Testing tools that must tell CommonJS from ES modules
- Comparing the two module systems
Minified JavaScript
sample-minified.js · 1.3 KB (1,297 bytes)
The sample script minified with esbuild, keeping a
/*!comment at the top. It prints exactly the same output as the original.- Testing formatters and source viewers
- Comparing minified and readable code
100 KB JavaScript file
sample-100kb.js · 100 KB (102,400 bytes)
A table of the first 14,082 prime numbers and a function that checks every one, padded with a comment to exactly 102,400 bytes.
- Upload and size-limit tests
- Parser and minifier benchmarks
Ways to test with them
- MIME types: put
sample-module.mjsandsample-module-math.mjsonline with a page that loads the first withtype="module". If the browser refuses it, the server isn't sendingtext/javascriptfor.mjs. - Module detection: run
sample-commonjs.jsandsample-module.mjsthrough your bundler, linter or Node.js version and check each is treated as the right kind of module. - Minifiers: minify
sample-script.jsand compare the output of both versions withnode; it should be identical, as it is forsample-minified.js. - Upload filters: many email services and upload forms block
.jsfiles outright. Try the samples to see where yours draws the line. - Upload limits:
sample-100kb.jsis exactly 102,400 bytes, for testing a limit at the boundary.
Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.
Put it online
Have a JavaScript file? Give it a link.
Drop a .js or .mjs file on 99helpers and it gets its own address in seconds. Opened in a browser, the link shows the code as text; pages can load it from there with a <script> tag.
Questions
JavaScript files, frequently asked
What is a .js file?
A JavaScript file: a plain-text program that a web browser runs as part of a web page, or that Node.js runs on a computer or server.
How do I open a JS file?
To read or edit it, open it in a text editor such as VS Code or Notepad. To run it, load it from an HTML page or run node file.js with Node.js installed. On Windows, don't double-click it: Windows will run it with Windows Script Host.
What's the difference between .js and .mjs?
.mjs always means an ES module (a file that uses import and export). A .js file can be either a classic script or a module, depending on how it's loaded and, in Node.js, on the "type" field in package.json.
What is the correct MIME type for JavaScript?
text/javascript, for both .js and .mjs, as set out in RFC 9239. application/javascript still works but is officially obsolete.
Is JavaScript the same as Java?
No. They are unrelated languages that share part of a name, chosen for marketing when JavaScript launched in 1995.
Why do I get "Cannot use import statement outside a module"?
The file uses import but was loaded as a classic script. In a browser, add type="module" to the <script> tag. In Node.js, rename it to .mjs or add "type": "module" to package.json.
Is it safe to open a .js file?
Inside a web page, JavaScript is sandboxed. A .js file on its own is different: on Windows, double-clicking it runs it with your user permissions, so treat unexpected .js attachments like programs and don't open them.
What is ECMAScript?
The official name of the JavaScript standard, ECMA-262, published by Ecma International. A new edition comes out every June; ECMAScript 2026 is the 17th.
Related formats
Other file types explained
Keep going
Related
Sources
- ECMA-262: ECMAScript 2026 Language Specification
- RFC 9239: Updates to ECMAScript Media Types
- MDN: JavaScript modules
- Node.js documentation: Modules, packages
- Computerworld: Tweaking WSH helps defend Windows PCs from malicious email attachments
Last reviewed 27 October 2026.