Conquering the File System: Working with Files in JavaScript

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Working with Files in JavaScript is a Must-Have

\n\n

Imagine you are the captain of a spaceship. Your task is to manage cargo holds, oxygen supplies, and the ship's log. In the world of web development, the file system is those cargo holds, and JavaScript is your control panel. Without the ability to work with files, you'll be stuck in orbit: you won't be able to save user settings, load a server configuration, or process log files.

\n\n

Many beginners think that JavaScript only lives in the browser and cannot touch files on the disk. This is a myth! With the advent of Node.js (and even in modern browsers via the File API), JavaScript has become a full-fledged tool for working with the file system. Today, we'll break down how to read, write, delete, and move files, as well as how to avoid the async trap.

\n\n

By the way, if you are just starting your programming journey, I recommend first studying JavaScript basics — this will help you understand the examples below faster.

\n\n

Where Does JavaScript Work with Files? Two Worlds — Two Approaches

\n\n

Before diving into the code, let's clarify: file operations in JS are divided into two camps.

\n\n

1. Server-Side JavaScript (Node.js)

\n

Here we have full access to the file system: creating, deleting, renaming, reading streams — whatever your heart desires. We work through the built-in fs (File System) module. It's like a Swiss Army knife for working with files.

\n\n

2. Client-Side JavaScript (Browser)

\n

The browser is a "sandbox" with restrictions. You can't just go and read any file from the user's computer (otherwise hackers would celebrate). But you can work with files that the user has chosen themselves via <input type="file">, or through the FileReader and Blob APIs.

\n\n

In this article, we will focus on Node.js, but at the end we'll give a bonus — an example for the browser.

\n\n

The fs Module: Your Main Tool

\n\n

In Node.js, working with files begins by importing the fs module:

\n\n
const fs = require('fs'); // old style\n// or\nimport fs from 'fs'; // if using ES modules
\n\n

The fs module has three modes of operation: synchronous, asynchronous with callbacks, and asynchronous with promises. We will use the latter — with async/await, as it is a modern and readable approach.

\n\n

Reading a File: From Simple to Complex

\n\n

Let's say we have a file data.txt with text. The simplest way to read it:

\n\n
import { readFile } from 'fs/promises';\n\nasync function readMyFile() {\n  try {\n    const data = await readFile('data.txt', 'utf-8');\n    console.log(data);\n  } catch (err) {\n    console.error('Read error:', err.message);\n  }\n}\n\nreadMyFile();
\n\n

What's important here? 'utf-8' is the encoding. If you don't specify it, you'll get a raw buffer that needs to be converted to a string. For text files, always specify the encoding.

\n\n

If the file is large (e.g., a 500 MB log file), reading it entirely is a bad idea. This is where streams come to the rescue:

\n\n
import { createReadStream } from 'fs';\nimport { createInterface } from 'readline';\n\nasync function readLargeFile() {\n  const stream = createReadStream('bigfile.log', 'utf-8');\n  const rl = createInterface({ input: stream });\n\n  for await (const line of rl) {\n    console.log('Line:', line);\n    // Process each line as it is read\n  }\n}\n\nreadLargeFile();
\n\n

Writing to a File: Creating and Appending

\n\n

Writing comes in two types: overwriting (write) and appending (append). The difference is obvious: write will erase the old file, append will add to the end.

\n\n
import { writeFile, appendFile } from 'fs/promises';\n\n//                

Blogs

Book Recommendations