Skip to main content
Node.js Basics
CHAPTER 05 Beginner

File System (fs module)

Updated: May 13, 2026
20 min read

# Node.js File System (fs Module)

Welcome to Chapter 5! One of the most powerful features of Node.js is its ability to interact directly with the operating system's file system. In a browser, JavaScript is strictly forbidden from touching a user's hard drive for security reasons. But on a server, reading and writing files (like logs, configuration files, or image uploads) is an everyday task.

---

1. Introduction

To work with the file system, Node.js provides a built-in Core Module named fs (File System). Because it is built-in, you don't need to install anything. You simply require('fs') and you immediately gain the power to create, read, update, and delete files (CRUD operations).

In this chapter, we'll explore both the Synchronous (blocking) and Asynchronous (non-blocking) ways to handle files.

---

2. Learning Objectives

By the end of this chapter, you will be able to:

  • Import the built-in fs module.
  • Differentiate between Synchronous and Asynchronous file operations.
  • Write new files to the hard drive (fs.writeFile).
  • Read existing files (fs.readFile).
  • Append data to existing files (fs.appendFile).
  • Delete files from the hard drive (fs.unlink).

---

3. Beginner-Friendly Explanations

Synchronous vs Asynchronous

Think of ordering coffee:
  • Synchronous (Blocking): You place an order, and the cashier makes you wait at the register until your coffee is done. Nobody else in line can order. In Node.js, fs.readFileSync stops all other code from running until the file is fully read.
  • Asynchronous (Non-Blocking): You place an order, get a receipt, and step aside. The cashier takes the next person's order. When your coffee is ready, they call your name (this is a callback function). In Node.js, fs.readFile reads the file in the background and lets the rest of your code run immediately.

Always prefer Asynchronous methods in backend development so you don't block the server from handling other users!

---

4. Syntax Explanation

Let's look at how to require the module and write a file asynchronously.

```javascript id="ch5-syntax-1" // 1. Require the built-in fs module (Notice there is no './' !) const fs = require('fs');

// 2. Syntax: fs.writeFile(path, data, callbackFunction) fs.writeFile('./message.txt', 'Hello, File System!', (err) => { if (err) { console.error("Failed to write file:", err); return; } console.log("File was created successfully!"); });

1234567891011121314151617181920
**Output Explanation:**
When this code runs, Node.js tells the operating system to create `message.txt` and write "Hello, File System!" inside it. While the OS does that, Node.js keeps running other code. Once the OS finishes, Node triggers the callback function. If it failed (e.g., hard drive full), `err` will hold an error object. Otherwise, `err` is null, and the success message prints.

---

## 5. Real-world Examples

**Where do we use the `fs` module?**
- **Logging Systems:** Every time a user encounters an error on your website, your Node app can `append` the error details and timestamp to an `error.log` file.
- **File Uploads:** When a user uploads a profile picture, Node.js reads the image stream and writes it to an `images` folder on the server.
- **Caching:** Saving complex database query results into a temporary `.json` file to speed up load times for subsequent users.

---

## 6. Multiple Code Examples

### Example 1: Reading a File

First, manually create a file called `greeting.txt` and type `Hello from a text file!` inside it.

javascript id="ch5-code-1" const fs = require('fs');

// readFile requires specifying 'utf8' encoding, // otherwise it returns a raw Buffer (binary data) fs.readFile('./greeting.txt', 'utf8', (err, data) => { if (err) { console.error(err); return; } console.log("File Contents:"); console.log(data); });

1234
### Example 2: Appending to a File

`writeFile` overwrites the whole file. If you want to add data to the end, use `appendFile`.

javascript id="ch5-code-2" const fs = require('fs');

const newLog = "\nUser logged in at " + new Date().toLocaleTimeString();

fs.appendFile('./activity.log', newLog, (err) => { if (err) throw err; console.log("Log saved!"); });

1234
### Example 3: Deleting a File

Deleting files uses the `unlink` method.

javascript id="ch5-code-3" const fs = require('fs');

// Deletes the file named temp.txt fs.unlink('./temp.txt', (err) => { if (err) { console.error("Could not find file to delete."); return; } console.log("File deleted successfully!"); });

12
### Example 4: Creating a Directory (Folder)

javascript id="ch5-code-4" const fs = require('fs');

fs.mkdir('./my-new-folder', (err) => { if (err) throw err; console.log("Folder created!"); });

123456789101112131415161718192021222324
---

## 7. Output Explanations

What is a **Buffer**?
If you forget to put `'utf8'` inside `fs.readFile`, your output might look like this: `<Buffer 48 65 6c 6c 6f 20 66 72 6f 6d 20 61 20 74 65 78 74 20 66 69 6c 65 21>`. 
Node.js reads files in raw binary (zeros and ones, represented here as hexadecimals) to be highly efficient. Passing `'utf8'` tells Node to translate that binary back into readable English text.

---

## 8. Common Mistakes

1. **Forgetting 'utf8':** Leading to confusing `<Buffer>` outputs instead of text.
2. **Callback Hell:** Nesting `readFile` inside `writeFile` inside `appendFile` creates messy, hard-to-read code. (We solve this later with `fs.promises`).
3. **Using Sync Methods in Production:** Using `fs.readFileSync()` or `fs.writeFileSync()` on a web server means every user has to wait while the server reads a file. Always use the callback or promise versions for web servers!

---

## 9. Best Practices

- **Always handle errors:** Never leave a callback empty. If a file operation fails (e.g., file doesn't exist, permission denied), your app will crash if you don't handle the `err` object.
- **Use `fs/promises` for modern code:** The Node.js team released a Promise-based version of `fs`. It allows you to use `async/await` instead of callbacks, making your code much cleaner.

*Quick Preview of fs promises:*

javascript const fs = require('fs/promises');

async function readMyFile() { const data = await fs.readFile('./data.txt', 'utf8'); console.log(data); }

123456789101112131415
---

## 10. Exercises

1. Write a script that creates a file named `quote.txt` containing your favorite quote using `fs.writeFile`.
2. Write a second script that reads `quote.txt` and logs its contents to the console using `fs.readFile`.
3. Try running `fs.unlink` on a file that doesn't exist to see what the error object looks like.

---

## 11. Mini Project: Notes manager app

**Objective:** Build a CLI app that lets you add notes to a file and read them back.

**Code (`notes.js`):**

javascript id="ch5-mini-project" // notes.js const fs = require('fs');

const command = process.argv[2]; const content = process.argv[3]; const filePath = './mynotes.txt';

if (command === 'add') { if (!content) { console.log("Please provide a note to add. (Wrap in quotes)"); process.exit(1); } const formattedNote = - ${content}\n; fs.appendFile(filePath, formattedNote, (err) => { if (err) throw err; console.log("✅ Note added successfully!"); });

} else if (command === 'read') { fs.readFile(filePath, 'utf8', (err, data) => { if (err) { console.log("No notes found or error reading file."); return; } console.log("\n--- My Notes ---"); console.log(data); console.log("----------------\n"); });

} else { console.log("Command not recognized. Use 'add' or 'read'."); } ``

Run it: node notes.js add "Learn Node.js FS module" node notes.js add "Buy groceries" node notes.js read

---

12. Coding Challenges

Challenge 1: Add a delete command to the notes app that uses fs.unlink to completely delete the mynotes.txt file.

Challenge 2: Write a script that checks if a file exists before trying to read it. (Hint: look up fs.existsSync() in the Node.js documentation).

---

13. MCQs with Answers

Q1: Which core module is used to interact with the file system? A) file B) os C) fs D) path Answer: C

Q2: If you use fs.readFile without specifying an encoding like 'utf8', what does it return? A) A String B) An Error C) A Buffer D) A Boolean Answer: C

Q3: Which method is non-blocking (asynchronous)? A) fs.writeFileSync() B) fs.writeFile() C) fs.readFileSync() D) fs.appendFileSync() Answer: B

Q4: Which function is used to delete a file? A) fs.delete() B) fs.remove() C) fs.trash() D) fs.unlink() Answer: D

---

14. Interview Questions

  1. 1. What is the difference between Synchronous and Asynchronous file operations in Node.js?
*Answer:* Synchronous operations block the Node.js event loop, preventing any other code from executing until the file task completes. Asynchronous operations run in the background and use a callback (or promise) to notify the app when finished, allowing the server to handle other tasks concurrently.
  1. 2. What is a Buffer in Node.js?
*Answer:* A Buffer is a temporary memory spot that gathers chunks of binary data. Node.js uses buffers to handle raw binary data streams, especially when reading files or receiving network packets.
  1. 3. How do you require a core module vs a local module?
*Answer:* Core modules are required by just their name (
require('fs')), while local custom modules must include a relative path (require('./myFile')).

---

15. FAQs

Q: Can fs write HTML files or JSON files? A: Yes! A file is just data. You can write fs.writeFile('index.html', '<h1>Hello</h1>', ...) and it will perfectly create an HTML file.

Q: Where does Node.js save the file if I don't give a full path? A: If you just say ./file.txt, it saves it in the current working directory—the folder from which you ran the node command in your terminal.

---

16. Summary

  • The fs module is built into Node.js and handles file operations.
  • Always use Asynchronous methods (writeFile, readFile) in production to avoid blocking the event loop.
  • Use 'utf8' encoding when reading files to get readable text instead of Buffers.
  • Use fs.appendFile to add text without overwriting, and fs.unlink to delete files.

---

17. Next Chapter Recommendation

When dealing with files, file paths can get very messy depending on whether you are using Windows (C:\folder\file) or Mac/Linux (/folder/file`). In Chapter 6: Node.js Path Module, we will learn how to handle file paths dynamically and safely across all operating systems!

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·