A Beginner’s Guide to the File System Module in Node.js
Learn how to use the “fs” module in Node.js
The file system module, or simply fs
, allows you to access and interact with the file system on your machine.
Using the fs
module, you can perform actions such as:
- Creating files and directories.
- Modifying files and directories.
- Deleting files and directories.
- Reading the content of files and directories.
This article will teach you the most common and useful fs
methods. Without further ado, let's see what those methods are.
How To Use fs
The file system module is a core Node.js module. That means that you do not have to install it. The only thing you have to do is import the fs
module into your file.
Thus, add the following line at the top of your file:
const fs = require('fs');
Now you can call any method from the file system module by using the prefix fs
.
Alternatively, you can import only the methods you want from the fs
API as follows:
const { writeFile, readFile } = require('fs');
However, in this tutorial, you will see the first option used — importing the whole fs
module.
Caveat
For this tutorial, you also need to import the path
module. It is another core Node.js module that allows you to work with file and directory paths.
Add the following line in your file after the import of the fs
module:
const path = require('path');
The path
module is not mandatory to work with the file system module. However, it helps!
Sync vs. Async
It’s important to note that by default, all the fs
methods are asynchronous. However, you can use the synchronous version by adding Sync
at the end of the method.
For instance, a method such as writeFile
becomes writeFileSync
. Synchronous methods complete the code synchronously, and thus they block the main thread. Blocking the main thread in Node.js is considered bad practice.
As a result, this tutorial uses the asynchronous methods from the file system module.
Write to a File
The first thing you will learn is how to write to a file. To write to a file from your Node.js application, you use the writeFile
method.
The writeFile
method takes the following arguments at a minimum:
- The name of the file
- The content
- A callback
If the specified file already exists, it replaces the old content with the content you provide as an argument. If the specified file does not exist, it creates a new file.
After importing the fs
and path
modules, write the following code in your application:
The code above creates a new file called content.txt
and adds the text This is my first file!
as the content. The callback function throws an error if there is one. Otherwise, it outputs to the console that the file creation succeeded.
Assuming you named your file fsPractice.js
, go to the terminal and run the command node fsPractice.js
. After you run the command, you should see the new file with the specified content.
There are other variants of writeFile
such as:
fs.writeFileSync
— Writes to the file synchronously.fsPromises.writeFile
— Uses the promise-based API to write to a file.
Check out this gist to see how your application should look at this point.
Read From a file
Before you read from a file, you need to create and store the path to the file. Here is where the path
module comes in handy.
With the join
method from the path
module, you can create the file path as follows:
const filePath = path.join(process.cwd(), 'content.txt');
The first argument, process.cwd()
, returns the current working directory. Now that you have the file path, you can read the content of the file.
Write the following code in your file:
fs.readFile(filePath, (error, content) => {
if (error) throw error;
process.stdout.write(content);
});
The readFile
method takes two arguments at the minimum:
- The path of the file
- A callback
If there is an error, it throws an error. Otherwise, it outputs the file content in the terminal.
If you go to the terminal and run the command node fsPractice.js
, you should see the file content in your terminal.
There are other variants of readFile
such as:
fs.readFileSync
— Writes to the file synchronously.fsPromises.readFile
— Uses the promise-based API to write to a file.
Check out this gist to see how your application should look at this point.
Read a Directory’s Content
Displaying the files inside a directory is quite similar to reading the content of a file. But instead of passing the file path, you pass the current working directory (you can pass any other directory).
After that, you pass a callback function to handle the response. Write the following code in your file:
fs.readdir(process.cwd(), (error, files) => {
if (error) throw error;
console.log(files);
});
Up to this point, you have only used process.stdout.write
to output stuff to the terminal. However, you can simply use console.log
like in the code snippet above.
If you run the application, you should get an array with all the files in your directory.
Check out this gist to see how your application should look at this point.
Delete a File
The file system module has a method that allows you to delete files. However, it’s important to note that it only works for files and not for directories.
When you call the unlink
method with the file path as an argument, it deletes the file. Add the following code snippet to your file:
fs.unlink(filePath, (error) => {
if (error) throw error;
console.log('File deleted!')
});
If you rerun the code, your file should be deleted!
Check out this gist to see how your application should look at this point.
Create a Directory
You can create a directory asynchronously by using the mkdir
method. Write the following piece of code in your file:
fs.mkdir(`${process.cwd()}/myFolder/secondFolder`, { recursive: true }, (err) => {
if (err) throw err;
console.log('Folder created successfully!');
});
Let’s take it step by step. First, you want to create a new folder inside the current working directory. As mentioned previously, you can get the current working directory with the cwd()
method from the process
object.
After that, you pass the folder or folders you want to create. However, this does not mean you have to create the new folder/s in the current working directory. You can create them anywhere.
Now, the second parameter is the recursive option. If you do not set it to true
, you cannot create multiple folders. The code above would give an error if you set the recursive
option to false
. Try it out to see!
However, if you want to create only one folder, you do not need to set the recursive
option to true
.
The following code would work just fine!
fs.mkdir(`${process.cwd()}/myFolder`, (err) => {
if (err) throw err;
console.log('Folder created successfully!');
});
Thus, I want to emphasize the use of recursive
. When you want to create folders inside folders, you need to set it to true
. It will create all the folders, even if they do not exist.
On the other hand, if you want to create only one folder, you can leave it as false
.
Check out this gist to see how your application should look at this point.
Delete a Directory
The logic to delete a directory is similar to that of creating one. If you look at the code you wrote to create a directory and the one below, you will see similarities.
Thus, write the following code in your file:
fs.rmdir(`${process.cwd()}/myFolder/`, { recursive: true }, (err) => {
if (err) throw err;
console.log('Folder/s deleted successfully!');
});
You use the rmdir
method from the file system module, and you pass the following arguments:
- The directory you want to delete
- The
recursive
property - A callback
If you set the recursive
property to true
, it deletes the folder and its contents. It's important to note that you need to set it to true
if the folder has content inside. Otherwise, you get an error.
The code snippet below only works if the folder is empty:
fs.rmdir(`${process.cwd()}/myFolder/`, (err) => {
if (err) throw err;
console.log('Folder/s deleted successfully!');
});
If you have other files and/or folders inside myFolder
, you get an error if you do not pass { recursive: true }
.
It’s important to know when to use the recursive
option and when not to in order to avoid issues.
Check out this gist to see how your application should look at this point.
Rename
Using the fs
module, you can rename both directories and files. The code snippet below shows how you can do it with the rename
method:
You can see that the rename
method takes three arguments:
- The first argument is the existing folder/file.
- The second argument is the new name.
- A callback.
Thus, to rename a file or directory, you need to pass the current file/directory’s name and the new name. After you run the application, the name of the directory/file should be updated.
It’s important to note that if the new path (e.g. the new name for the file/folder) already exists, it will be overwritten. Therefore, be sure not to overwrite existing files/folders by mistake.
Check out this gist to see how your application should look at this point.
Add Content to a File
With the file system module, you can also add new content to an existing file. The appendFile
method allows you to do that.
If you compare the writeFile
and appendFile
methods, you can see that they are similar. You pass the file path, the content, and a callback.
fs.appendFile(filePath, '\nNew data to be added!', (err) => {
if (err) throw err;
console.log('New content added!');
});
The code snippet above illustrates how you can add new content to an existing file. If you run the application and open your file, you should see the new content inside.
Check out this gist to see how your application should look at this point.
Conclusion
If you are reading this, it means that you can now:
- Create files and directories.
- Modify files and directories.
- Delete files and directories.
- Read the content of files and directories.
Well done! However, the file system module is more complex, and I encourage you to check the official documentation. In the official documentation, you can see all the methods.
Do you want to learn how to code? Check these 20 best places to learn how to code.
If you are looking to learn JavaScript, check these 5 best JavaScript resources.
Here is a list with programming project ideas for beginners.
Check these JavaScript ES2020 features.