I/O Operations in JavaScript
Learn console output, reading stdin, and synchronous vs asynchronous file I/O in JavaScript with Node.js and Docker-ready examples
Input and output are how a program talks to the outside world - the terminal, the keyboard, and the filesystem. In the browser, JavaScript’s “I/O” is the DOM and the network. On the server, Node.js gives JavaScript full access to standard input, standard output, and the file system through built-in modules.
What makes I/O in JavaScript distinctive is its event-driven, non-blocking nature. Because JavaScript grew up in the browser - where blocking the main thread freezes the whole page - the language and Node.js favor asynchronous I/O. Reading a large file doesn’t stop everything; instead you get a promise (or a callback) that resolves when the data is ready. Node.js also offers synchronous versions for scripts and startup code, giving you both styles.
In this tutorial you’ll write to the console with several output methods, read a line of input from stdin, and read and write files using both the synchronous fs API and the asynchronous promise-based API. You’ll also see how JavaScript surfaces I/O errors.
Console Output
You’ve already seen console.log(). Node.js offers several more ways to write to the two standard streams: stdout for normal output and stderr for errors and diagnostics.
Create a file named io_operations.js:
| |
console.log() appends a newline and separates arguments with spaces, while process.stdout.write() gives you raw control with no formatting. The console.error() method behaves like console.log() but sends output to the stderr stream - useful for separating diagnostics from real results when piping output.
Reading Input from stdin
To read from the keyboard (standard input), Node.js provides the readline module, which reads input one line at a time. Because input arrives asynchronously, you supply a callback that runs once the line is available.
Create a file named read_input.js:
| |
The rl.question() method prints a prompt and waits for a line of input without blocking the event loop. When the user presses Enter, the callback fires with the typed text. You must call rl.close() to release stdin so the program can exit.
Synchronous File I/O
The fs (file system) module reads and writes files. Its synchronous methods - suffixed with Sync - block until the operation finishes and return the result directly. They’re convenient for simple scripts and setup code.
Create a file named file_io.js:
| |
Passing 'utf8' as the encoding makes readFileSync return a string; without it you’d get a raw Buffer of bytes. Note that writeFileSync overwrites the whole file, while appendFileSync adds to the end - a distinction that matters when building up log files.
Asynchronous File I/O and Error Handling
The idiomatic Node.js approach is non-blocking I/O. The fs/promises module returns promises, which pair naturally with async/await. This lets your program stay responsive while the operating system does the slow disk work. Wrapping the calls in try/catch handles I/O errors cleanly.
Create a file named async_file.js:
| |
When readFile cannot find missing.txt, it rejects the promise, await throws, and control jumps to the catch block. The error object’s code property (ENOENT = “Error NO ENTry”) gives a stable, machine-readable reason - far more useful for logic than parsing the human-readable message.
Running with Docker
| |
The -v $(pwd):/app flag mounts your current directory into the container so files created by file_io.js and async_file.js appear on your host machine. The -i flag on the stdin example keeps input open so echo can feed the prompt.
Expected Output
Running io_operations.js:
Standard output line
Sum: 5 Done
Name: Ada, Age: 36, Score: 99.5
Learning JavaScript is fun!
No newline here... continued on same line
This message goes to stderr
{ name: 'Grace', role: 'admin' }
Running read_input.js with Ada as input:
What is your name? Hello, Ada! Welcome to JavaScript I/O.
Running file_io.js:
File written: languages.txt
Appended one line
--- File contents ---
Fortran - 1957
Lisp - 1958
COBOL - 1959
JavaScript - 1995
--- Line by line ---
1: Fortran - 1957
2: Lisp - 1958
3: COBOL - 1959
4: JavaScript - 1995
Exists: true
Running async_file.js:
Async I/O complete
I/O error: ENOENT
Key Concepts
- Two output streams -
console.log()writes to stdout whileconsole.error()writes to stderr, letting you separate results from diagnostics when piping or redirecting. process.stdout.write()gives raw output with no added newline or argument formatting, unlikeconsole.log().- Synchronous vs asynchronous -
fs.readFileSync()blocks until done;fs/promiseswithawaitis non-blocking and is the idiomatic Node.js choice for anything performance-sensitive. - Encoding matters - pass
'utf8'to file reads to get a string; omit it to get a rawBufferof bytes. - Write vs append -
writeFileoverwrites the entire file, whileappendFileadds to the end without erasing existing content. - Error codes over messages - I/O failures expose a stable
err.code(likeENOENT) that’s reliable for program logic, unlike the human-readable message. readlinefor input - reading stdin is callback- or promise-based because input arrives over time; remember toclose()the interface so the program can exit.
Comments
Loading comments...
Leave a Comment