How to list files in a folder in Node
By Flavio Copes
Learn how to list the files in a folder in Node.js using the fs module readdirSync() method to get an array of filenames you can then iterate over.
To get an array with the list of the files contained in a folder in Node.js, first import the fs built-in module, then call fs.readdirSync() passing the folder name you want to read:
import fs from 'fs'
const filenames = fs.readdirSync('content')
This returns an array of names, like ['first-post.md', 'second-post.md', 'images']. Both files and subfolders show up in the list, with no path attached. Just the names.
You can use a relative or absolute path.
Then you can iterate over the file names in this way:
filenames.map((filename) => {
console.log(filename)
})
Filtering the list
Often you don’t want everything. When I read a content folder for a blog, I only care about markdown files. filter() handles that:
const posts = filenames.filter((filename) => filename.endsWith('.md'))
You can also exclude hidden files, the ones starting with a dot:
const visible = filenames.filter((filename) => !filename.startsWith('.'))
This matters more than it seems. macOS drops .DS_Store files everywhere, and they will show up in your list sooner or later.
Where does the relative path point?
Here’s the pitfall that bites everyone at some point. A relative path like content is resolved from the current working directory, the folder you launched Node from. Not from the folder where your script file lives.
Run node src/index.js from your project root, and content means the content folder in the root. Run the same script from inside src, and Node looks for src/content instead. You get this error:
Error: ENOENT: no such file or directory, scandir 'content'
The fix is building an absolute path based on the script location, with import.meta.dirname:
import fs from 'fs'
import path from 'path'
const dir = path.join(import.meta.dirname, 'content')
const filenames = fs.readdirSync(dir)
Now the script finds the folder no matter where you run it from. import.meta.dirname is available in recent Node.js versions; on older ones you can derive the same value from import.meta.url.
If the folder doesn’t exist at all, readdirSync() throws the same ENOENT error. Check the path before blaming the code.
Related posts about node: