How to check if a file exists in Node.js

By

Learn how to check if a file exists in Node.js using fs.existsSync() for a synchronous check, or fs.access() for an asynchronous, non-blocking approach.

~~~

To check if a file exists in Node.js, use the fs.existsSync() method. It returns true if the path exists, false if it doesn’t:

const fs = require('fs')

if (fs.existsSync('./notes.txt')) {
  //file exists
}

This method is synchronous. The program stops and waits until the check is done. That’s fine in a CLI script, or when your app starts up. It’s a problem inside a server handling requests, because it blocks the event loop.

Note that existsSync() does not throw when the file is missing. It just returns false. You only get an exception for unexpected problems, like passing an invalid path argument.

How do you check asynchronously?

To check if a file exists without blocking, use fs.access(). It verifies the file is reachable without opening it. If the file does not exist, the callback receives an error:

const fs = require('fs')

fs.access('./notes.txt', fs.constants.F_OK, (err) => {
  if (err) {
    console.error(err)
    return
  }

  //file exists
})

fs.constants.F_OK means “check that the path exists”. You can pass other constants to check permissions too: fs.constants.R_OK checks the file is readable, fs.constants.W_OK checks it’s writable.

Be careful with check-then-use

There’s a subtle problem with checking for a file and then reading it. The file could disappear between the two operations. Another process might delete it, or your own code might.

If you plan to read the file right after, skip the check. Try the read directly, and handle the error:

const fs = require('fs')

fs.readFile('./notes.txt', 'utf8', (err, data) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.log('file does not exist')
      return
    }
    throw err
  }

  console.log(data)
})

ENOENT is the error code Node uses for “no such file or directory”. This approach avoids the race entirely, because there’s a single operation instead of two.

Use existsSync() or fs.access() when the existence itself is the answer you need, for example to decide whether you should create a default configuration file.

Tagged: Node.js · All topics
~~~

Related posts about node: