fs.existsSync()

Tests whether a path exists on the filesystem and returns true or false.

Signature
fs.existsSync(path)
  • Added in Node.js v0.1.21

Parameters

ParameterTypeDescription
$path<string> | <Buffer> | <URL>The path to test. It may name a file, a directory, a symlink target or any other filesystem entry; symlinks are followed, so a dangling symlink reports false.

Return value

booleantrue if the path exists, false otherwise. It returns false rather than throwing for any error, including permission failures on a parent directory.

Errors

Never throws for filesystem conditions &mdash; every failure, including EACCES, is reported as false. It does throw ERR_INVALID_ARG_TYPE if path is not a string, Buffer or URL.

Changelog

  • PHP v7.6.0path may be a WHATWG URL object using the file: protocol.

fs.existsSync() answers one question: is there something at this path right now? It returns a boolean and never throws for filesystem reasons. Unlike the long-deprecated callback fs.exists(), the synchronous form is not deprecated and is fine to use.

Do not use it as a guard before an operation

The classic pattern — check, then read or create — contains a race: the file can appear or vanish between the two calls, and on a busy system it does. It also doubles the syscalls. Just attempt the operation and handle the error code:

try {
  return JSON.parse(fs.readFileSync(file, 'utf8'));
} catch (err) {
  if (err.code === 'ENOENT') return defaults;
  throw err;
}

It tells you nothing about type or access

true only means “something is here”. A directory returns true where you expected a file. And because every error collapses to false, a file you genuinely lack permission to see is indistinguishable from one that does not exist — use fs.statSync() or fs.accessSync() when you need to know which.

Where it fits cleanly is one-off reporting in scripts and CLIs: printing whether an expected artefact was produced, or deciding whether to show a setup hint.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Print a helpful message from a CLI when an expected config file has not been created yet.
  • Confirm in a script or test that a build step actually produced its output file.
  • Decide whether to seed a fresh data directory on first run of a tool.

Frequently asked questions

Is fs.existsSync deprecated?

No. The callback-based fs.exists() is deprecated because its callback signature is inconsistent with every other fs function, but fs.existsSync() and fs.promises.access() are both current and supported.

Should I use fs.existsSync before reading a file?

Generally no. Reading directly and catching ENOENT avoids both the extra syscall and the race window in which the file can be deleted between the check and the read. Use existsSync for reporting, not for guarding.

How do I check whether a path is a directory rather than a file?

Use fs.statSync(path).isDirectory(), wrapped in try/catch for the missing-path case. fs.existsSync() returns true for any kind of entry and cannot distinguish files from directories.

More examples

True does not mean it is a file

The directory reports true from existsSync yet false from isFile(). If your next step is readFileSync, that true is not the check you wanted &mdash; the read would fail with EISDIR.

Example · javascript
const fs = require('node:fs');

fs.mkdirSync('cache', { recursive: true });
fs.writeFileSync('cache/data.json', '{}');

console.log('cache is a path that exists:', fs.existsSync('cache'));
console.log('but it is not a file:', fs.statSync('cache').isFile());
console.log('cache/data.json is a file:', fs.statSync('cache/data.json').isFile());

fs.rmSync('cache', { recursive: true, force: true });

Skip the check and handle the error instead

Both cases are handled with one syscall each and no race window. The output shows the real contents for the file that exists and the fallback for the one that does not, which is what an existsSync guard would have given you less safely.

Example · javascript
const fs = require('node:fs');

function readOrDefault(file, fallback) {
  try {
    return fs.readFileSync(file, 'utf8');
  } catch (err) {
    if (err.code === 'ENOENT') return fallback;
    throw err;
  }
}

fs.writeFileSync('present.cfg', 'mode=fast');
console.log(readOrDefault('present.cfg', 'mode=default'));
console.log(readOrDefault('gone.cfg', 'mode=default'));
fs.unlinkSync('present.cfg');

Discussion

  • Be the first to comment on this lesson.