Check synchronously if file/directory exists in Node.js
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
In Node.js, various filesystem (fs) methods are used to interact with files and directories. An important aspect of managing filesystem tasks is checking the existence of a file or directory. Ensuring a file or directory exists before performing operations on it is critical to avoid errors and ensure that your applications run smoothly.
Checking Existence Synchronously in Node.js
Node.js provides synchronous and asynchronous methods for interacting with the filesystem through the fs module. Synchronous methods will block the Node.js event loop while they execute, which can lead to performance issues in scalable applications. However, for certain scenarios, particularly scripts or simple backend applications where the impact on performance is minimal, synchronous methods can be preferable for their simplicity and ease-of-use.
The fs.existsSync(path) Method
The primary method for checking if a file or directory exists synchronously is fs.existsSync(). It takes a single argument—the path to the file or directory you want to check—and returns true if the file exists, and false otherwise.
Here's an example of how to use fs.existsSync():
This method is straightforward and works well for simple checks. However, it's important to note that fs.exists() was deprecated due to its inconsistent callback pattern and because it could not differentiate between true absence of the file and permission/access errors. Thus, the use of fs.existsSync() is generally acceptable in contexts where the impact of synchronous I/O is limited.
Alternatives: Using Try-Catch with fs.statSync() or fs.accessSync()
Using fs.existsSync() can sometimes be seen as an antipattern particularly when used in larger, more interactive applications because its synchronous nature can halt the execution of all other code. As an alternative, you can use fs.statSync() or fs.accessSync() within a try-catch block to check for the existence of a file or directory.
Example using fs.statSync():
Example using fs.accessSync():
Both fs.statSync() and fs.accessSync() throw an error if the file does not exist, which can be caught and handled appropriately. fs.statSync() provides additional information about the file like size, creation date, etc., whereas fs.accessSync() is used to check user permissions.
When to Use Synchronous Methods
The use of synchronous methods in Node.js is appropriate under circumstances where the delay caused by blocking the event loop does not impact the application significantly. These circumstances might include:
- Startup checks in an application (ensuring config files or essential data files are present)
- Scripting in local and small-scale applications
- When running operations in parallel is unnecessary
Summary Table
| Method | Use case | Returns | Blocking |
fs.existsSync() | Quick existence check | Boolean | Yes |
fs.statSync() | Check existence with detailed file information | Object | Yes |
fs.accessSync() | Check file accessibility (permissions) | None (throws error if inaccessible) | Yes |
Conclusion
Checking whether a file or directory exists synchronously in Node.js can be efficiently performed using fs.existsSync(), fs.statSync(), or fs.accessSync(). Each method has its appropriate use cases and can be a valuable part of a Node.js developer's toolkit, especially in less complexity-constrained environments. However, for larger applications with high concurrency requirements, asynchronous methods are usually preferable to avoid blocking the Node.js event loop.

