Skip to Content
Course content

146: Reading and Writing Files in Node

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Up until now, we've been writing scripts that live and die in the terminal. Once you stop the process, your data vanishes. To build anything actually useful—like a CLI tool or a simple server—you need a way to persist data. In Node, that means getting comfortable with the fs (File System) module.

I prefer using the promises-based API over the old callback style. Callbacks lead to "callback hell" pretty quickly, and since we've already covered async/await, it's the only way to go for clean, readable code.

Setting up our Activity Logger

Let's build a simple activity logger. The goal is a script where we can pass a message, and it appends that message along with a timestamp to a file called log.txt. If the file doesn't exist, Node should just create it for us.

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

async function logActivity(message) {
  const timestamp = new Date().toISOString();
  const entry = `[${timestamp}] ${message}\n`;
  
  try {
    await fs.appendFile('log.txt', entry);
    console.log('Logged successfully!');
  } catch (err) {
    console.error('Something went wrong writing to the file:', err);
  }
}

logActivity('User logged in');
logActivity('Updated profile settings');

I used appendFile here instead of writeFile. If I had used writeFile, it would overwrite the entire file every time I called the function, and I'd only ever have the very last log entry. Not exactly helpful for a log.

Reading the log back into the console

Now that we're saving data, we need to be able to read it. I'll add a function to our script that reads the entire log.txt file and prints it to the terminal so we can verify our entries.

async function readLogs() {
  try {
    const data = await fs.readFile('log.txt');
    console.log('--- Current Logs ---');
    console.log(data);
  } catch (err) {
    console.error('Could not read the file:', err);
  }
}

readLogs();

Wait, why am I seeing numbers?

If you run the code above, you'll notice something weird. Instead of seeing your text logs, you'll see something like <Buffer 5b 32 30 32 34...>. This is a classic "gotcha" in Node.js.

By default, fs.readFile returns a Buffer—a raw sequence of bytes. Node doesn't assume you want a UTF-8 string because you might be reading an image, a PDF, or some other binary file. I forgot to specify the encoding, which is a mistake I still make occasionally when I'm rushing.

To fix this, we just need to pass 'utf8' as the second argument. This tells Node to decode those bytes into a human-readable string.

async function readLogs() {
  try {
    // Adding 'utf8' here is the magic fix
    const data = await fs.readFile('log.txt', 'utf8');
    console.log('--- Current Logs ---');
    console.log(data);
  } catch (err) {
    console.error('Could not read the file:', err);
  }
}

Wrapping it into a usable utility

To make this feel like a real tool, let's allow it to take arguments from the command line. We can use process.argv to decide whether we want to write a new log or read the existing ones.

async function main() {
  const [,, command, ...args] = process.argv;

  if (command === 'add') {
    const message = args.join(' ');
    await logActivity(message);
  } else if (command === 'read') {
    await readLogs();
  } else {
    console.log('Usage: node logger.js [add "message" | read]');
  }
}

main();

Now you can run node logger.js add "Finished the FS lesson" to save a note, or node logger.js read to see everything you've tracked. It's simple, but this pattern of reading and writing is the foundation for almost every backend application.




📋 Practical Task

Build a JSON Configuration Updater

Create a script that manages a config.json file. Your script should perform the following steps:

  • Check if config.json exists. If it doesn't, create it with a default object: { "theme": "light", "notifications": true }.
  • Read the current contents of config.json.
  • Change the theme value to "dark".
  • Write the updated object back to the file.

Requirement: Use fs/promises and ensure you use JSON.parse() and JSON.stringify() to handle the data conversion between the file's string format and JavaScript objects.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.