Module F-3·20 min read

The fs module, sync vs async variants, path.join and path.resolve, process.env and process.argv — reading from and writing to the real world.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

Module F-3 — Working with Files, Paths, and the Environment

What this module covers: The moment you write a server, a script, or a CLI tool, you need to read files, write logs, parse paths, and pull configuration from the environment. This module covers Node.js's fs module for file I/O, the path module for platform-safe path manipulation, and the process object for environment variables and command-line arguments. These three are in practically every Node.js program you will ever write.


The fs Module

The fs (file system) module is how Node.js reads and writes files on disk. Every operation comes in two flavours: synchronous (blocks until complete) and asynchronous (non-blocking, uses a callback or Promise). We'll cover when to use each.

Reading a File

Async with callback (old style — you will see this in legacy code):

javascript

The callback receives two arguments by convention: err first, then the result. If err is not null, something went wrong. This error-first callback pattern is a Node.js convention you will see everywhere in older code.

A gotcha worth flagging early: in the example above, the second argument to fs.readFile() is 'utf8' — the encoding. If you leave that argument out, Node.js does not give you a string at all; it gives you a raw Buffer (a chunk of binary data). Forgetting the encoding is one of the most common beginner mistakes with fs — you console.log() what you expect to be text and instead see something like <Buffer 68 65 6c 6c 6f>. Always pass 'utf8' explicitly when you want a string back.

A limit worth knowing: fs.readFile() (in any of its forms — callback, Promise, or sync) reads the entire file into memory before your callback runs or your await resolves. For a config file or a small log, that's fine. For a multi-gigabyte file, it isn't — you'll either exhaust memory or wait far longer than necessary before processing the first byte. When files get large, the right tool is a stream, which processes data in chunks as it arrives instead of loading it all at once. Streams are covered in depth in Phase 2.

Async with Promises (modern style — use this):

javascript

node:fs/promises is the Promise-based version of the fs module, available since Node.js 14. Always prefer this in new code — it works with async/await and avoids callback nesting.

Synchronous (avoid in servers, fine in scripts):

javascript

readFileSync blocks the entire Node.js process until the file is read. In a script that runs once and exits, this is fine. In a server handling concurrent requests, never use it — you will block every other request while one request waits for a file read.

Writing a File

javascript

Common flags:

  • 'w' — write (creates or overwrites)
  • 'a' — append (creates or adds to end)
  • 'wx' — write, but fail if file already exists (useful for "create once" files)

Checking if a File Exists

javascript

Avoid the old fs.existsSync() pattern. It creates a race condition: by the time you act on the result (open the file), another process may have deleted it. The correct pattern is to attempt the operation and handle the error — exactly what try/catch around fs.access does.

Creating Directories

javascript

Listing Directory Contents

javascript

Deleting Files and Directories

javascript

Renaming and Moving Files

javascript

Getting File Metadata

javascript

The path Module

File paths are one of the most common sources of bugs in cross-platform code. On Windows, paths use backslashes (C:\Users\jatin). On macOS and Linux, they use forward slashes (/home/jatin). The path module abstracts this so your code works everywhere.

javascript

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.