How can I synchronously check, using node.js, if a file or directory exists?
In Node.js, you have a few ways to check if a file or directory exists synchronously:
1. Using fs.existsSync()
While the Node.js documentation discourages using fs.existsSync()
in asynchronous code, it remains a straightforward way to check existence synchronously.
const fs = require('fs'); const path = '/path/to/file-or-directory'; if (fs.existsSync(path)) { console.log('Path exists!'); } else { console.log('Path does not exist.'); }
Note: This will block the event loop briefly, so use it sparingly and avoid in performance-critical sections.
2. Using fs.statSync()
with a Try/Catch
Another reliable approach is using fs.statSync()
inside a try/catch
block. If statSync
succeeds, the path exists (and you can further inspect if it’s a file or directory). If it throws an error (like ENOENT
), the path does not exist.
const fs = require('fs'); const path = '/path/to/file-or-directory'; try { const stats = fs.statSync(path); if (stats.isFile()) { console.log('It is a file.'); } else if (stats.isDirectory()) { console.log('It is a directory.'); } // If we got here, the path exists. } catch (err) { if (err.code === 'ENOENT') { console.log('Path does not exist.'); } else { // Some other error occurred. throw err; } }
Pros:
- Provides more detail (e.g., whether it’s a file or directory).
- Throwing an exception if the file doesn’t exist can be useful in some workflows.
Cons:
- Requires exception handling just for existence checks.
3. Using fs.accessSync()
fs.accessSync()
checks if the process has permission to access the path. If the path doesn’t exist or is inaccessible for another reason, it throws an error:
const fs = require('fs'); const path = '/path/to/file-or-directory'; try { fs.accessSync(path, fs.constants.F_OK); console.log('Path exists and is accessible.'); } catch (err) { console.log('Path does not exist or cannot be accessed.'); }
Pros:
- Can check for specific permissions (e.g.,
R_OK
,W_OK
). - Also uses a
try/catch
approach.
Cons:
- If you only need to know if it exists (and not about permissions), this might be more detail than necessary.
Recommended Resource
Which Method to Choose?
fs.existsSync()
: Easiest for a simple yes/no check, but the Node.js docs don’t recommend it for production code due to potential race conditions and synchronous blocking. Still acceptable if used sparingly or in scripts where performance is less critical.fs.statSync()
with a try/catch: Tells you not only if it exists but also whether it’s a file or directory.fs.accessSync()
: Useful if you specifically want to test for accessibility and not just existence.
Any of these will block your Node.js event loop, so only use them where synchronous operations are acceptable—often in startup scripts or places where the performance impact is negligible. For high-performance or real-time scenarios, prefer the asynchronous fs.access
, fs.stat
, or fs.exists
(though the callback version of fs.exists
is deprecated, using fs.stat
or fs.access
with callbacks or promises is the recommended approach).