Your First Program
Scope: running a script with node, reading a file, and
understanding the two module systems you'll meet. All commands
below were run and verified with Node v24.
Run a script
Create hello.mjs:
console.log("Hello, world!");
node hello.mjs
Check: prints Hello, world!
console.log is how you print. The .mjs extension means "this
file uses ES modules" — more on that below.
Do something real: read a file
Create readit.mjs:
import { readFile } from "node:fs/promises";
const text = await readFile("hello.mjs", "utf8");
console.log("File has", text.length, "characters");
node readit.mjs
Check: prints something like File has 32 characters.
Two things to notice:
node:fs/promises— thenode:prefix marks a built-in module (files, in this case). The/promisesversion returns promises instead of using callbacks — the modern way.- Top-level
await— you can useawaitdirectly in a module file, no wrapper function needed. (This only works in modules, which is one reason we use.mjs.)
The two module systems (read this once)
JavaScript has two ways to share code between files, and you will meet both:
| ES modules (modern) | CommonJS (older) | |
|---|---|---|
| File extension | .mjs |
.cjs (or .js) |
| Import | import { x } from "..." |
const { x } = require("...") |
| Export | export function x() |
module.exports = ... |
Use ES modules (.mjs, import) for everything new. You'll
still read CommonJS in older libraries and tutorials — now you
know what you're looking at.
The plain .js extension is ambiguous: Node treats it as
CommonJS unless the nearest package.json says "type":
"module". Using .mjs/.cjs explicitly sidesteps the whole
question. (See Modules and npm.)
Arguments and exiting
// args.mjs
console.log("You passed:", process.argv.slice(2));
node args.mjs one two
Check: prints You passed: [ 'one', 'two' ]
process.argvholds command-line arguments; the first two entries are the node binary and the script path, so real arguments start at index 2.process.exit(1)ends the program with a failure code (0 = success, anything else = something went wrong).
The REPL
Type node with no arguments for an interactive prompt — handy
for trying snippets:
$ node
> 2 + 2
4
> .exit
Press Ctrl+C twice or type .exit to leave.
Check
- [ ] You can run a
.mjsscript and explain the extension - [ ] You can read a file with
node:fs/promisesand top-level await - [ ] You can recognize CommonJS (
require) vs ES modules (import) in the wild
Next: Variables and Types.