How to get the names of all the files in a folder in Node
By Flavio Copes
Learn how to list all the files and folders inside a directory in Node.js using fs.readdirSync, then inspect each one with lstatSync and isDirectory().
To get the names of all the files contained in a folder using Node.js, use the fs.readdirSync() method:
const fs = require('fs')
const dir = '/Users/flavio/folder'
const files = fs.readdirSync(dir)
for (const file of files) {
console.log(file)
}
readdirSync() returns an array of names, not full paths. If the folder contains a notes.txt file and a projects subfolder, you get ['notes.txt', 'projects']. Files and directories are mixed together in the same array.
The call is synchronous: the program waits for the filesystem before moving on. For a script or a build step, that’s perfect.
How do you tell files and folders apart?
Once you have a file reference, you can get its details using fs.lstatSync():
const path = require('path')
//...
//inside the `for` loop
const stat = fs.lstatSync(path.join(dir, file))
This is useful to distinguish files from folders, using the stat.isDirectory() method. Here’s the full program:
const fs = require('fs')
const path = require('path')
const dir = '/Users/flavio/folder'
const files = fs.readdirSync(dir)
for (const file of files) {
const stat = fs.lstatSync(path.join(dir, file))
if (stat.isDirectory()) {
console.log(`${file} is a folder`)
} else {
console.log(`${file} is a file`)
}
}
A common mistake
Notice the path.join(dir, file) call. The names returned by readdirSync() are bare names, without the folder they live in.
If you pass file directly to lstatSync(), Node resolves it against the current working directory. Unless you happen to run the script from inside that exact folder, you get an ENOENT error. Joining the name with the directory path fixes it.
One more detail worth knowing: lstatSync() does not follow symbolic links. A symlink pointing to a folder reports isDirectory() as false, because the link itself is not a directory. If you want to inspect the target of the link instead, use fs.statSync(), which follows it.
A shortcut: withFileTypes
You can skip the lstatSync() calls entirely. Pass the withFileTypes option and readdirSync() returns fs.Dirent objects instead of strings:
const entries = fs.readdirSync(dir, { withFileTypes: true })
for (const entry of entries) {
console.log(entry.name, entry.isDirectory())
}
Each entry carries its name and its type. One filesystem call instead of one per file, and no path joining needed for the type check.
fsandpathare built-in modules, no need to install them using npm
Related posts about node: