Recursive ReadDir
Recursive Directory Reading • Sync And Async Usage • Flexible Filters • Depth Control
📖 Fast, type-safe recursive directory reader for Node.js with depth control, entry filtering, and sync/async APIs. 📁
📃 Table of Contents
🤖 Features
- 📂 Reads directories recursively with precise depth control
- 🎯 Filters results by files-only, directories-only, or all entries
- ⚡ Supports both synchronous and asynchronous operations
- 🧩 Accepts custom filter functions for advanced selection
- ✨ Optionally adds trailing slashes to directory paths
- 🛡️ Skips unreadable entries without stopping traversal
- 🏗 Provides a fluent class API for easy configuration
- 💻 Cross-platform paths, powered by uPath
🎯 Motivation
This npm module was built to provide a reliable and efficient way of listing directories while another project was being developed - a Visual Studio Code extension called New Folder, where a custom QuickPick dialog was required to allow the selection of a root directory.
🕵🏼 Usage
Install it by executing any of the following, depending on your preferred package manager:
pnpm add @igorskyflyer/recursive-readdiryarn add @igorskyflyer/recursive-readdirnpm i @igorskyflyer/recursive-readdir🤹🏼 API
λ Function-based
async function readDir(directory: string, options: RecursiveDirOptions): Promise<string[]>Asynchronously gets files/directories inside the given directory.
Params
directory: string - the directory whose files/directories should be listed,
options: RecursiveDirOptions - additional options.
function readDirSync(directory: string, options: RecursiveDirOptions): string[]Synchronously gets files/directories inside the given directory.
Params
directory: string - the directory whose files/directories should be listed,
options: RecursiveDirOptions - additional options.
💎 Class-based
For own convenience and code-reuse you can use the class-based approach.
Define the options once and (re)call the readDirSync()/readDir() when needed.
class RecursiveDirAvailable methods
function readDirSync(directory: string): string[]Synchronously gets files/directories inside the given directory.
Params
directory: string - the directory whose files/directories should be listed.
function readDir(directory: string): Promise<string[]>Asynchronously gets files/directories inside the given directory.
Params
directory: string - the directory whose files/directories should be listed.
function entries(value: Entry): RecursiveDirSets the entries property which controls whether to list files-only, directories-only or both (default).
Params
value: Entry - a value with three possible values - provided as class consts,
Entry.All,Entry.FilesOnly,Entry.DirectoriesOnly.
function maxDepth(value: Depth): RecursiveDirSets maxDepth which controls how many child directories' entries are being listed.
Params
value: Depth - the new maxDepth value.
You can use the 2 predefined values or use an arbitrary value. The predefined values are as follows:
Depth.All= -1 - return all subdirectories entries,Depth.Root= 0 (default) - return only root directory's entries.
ℹ️ NOTE
Why the default value of
maxDepthis NOTDepth.All?It is simple: the value must be explicitly set, since traversal through all child subdirectories is highly resource‑ and time‑consuming. For example, if the directory parameter were set to the root of a drive in combination with
maxDepth = Depth.All, the operation could become extremely heavy.
To use arbitrary values the provided value parameter must comply with the expression maxDepth >= Depth.Root i.e., maxDepth >= 0.
The value of 0 means that only directory entries found in the directory specified when calling either readDir() or readDirSync() methods are returned. By increasing the number we can set the depth/level of subdirectories that the method should return, e.g.
maxDepth = Depth.Root
maxDepth(Depth.Root)
// return only the files/directories in the current directorymaxDepth = 3
maxDepth(3)
// return the files/directories in the current director files/directories 3-levels deepmaxDepth = Depth.All
maxDepth(Depth.All)
// return all child files/directories in the current directoryfunction filter(value: FilterCallback): RecursiveDirSets filter predicate function used for filtering directory entries (directories/files).
Params
value: FilterCallback - the filter function to use when filtering directory entries.
function addTrailingSlash(value: boolean): RecursiveDirSets whether a trailing slash should be added to directory entries.
Params
value: boolean - a Boolean indicating whether a trailing slash should be added to directory entries.
🗒️ Examples
import { readDirSync, Depth, Entry, RecursiveDir } from '@igorskyflyer/recursive-readdir'
const testingPath: string = './somePath'
// Function-based approach
console.log(readDirSync('non-existent-directory')) // returns []
console.log(
readDirSync(testingPath, {
maxDepth: Depth.All,
filter: (entry) => entry.isDirectory,
})
) // returns only subdirectories (all subdirectories)
// the following can be used interchangeably
console.log(
readDirSync(testingPath, {
maxDepth: Depth.All,
entries: Entry.DirectoriesOnly,
})
) // returns only subdirectories (all subdirectories)
console.log(
readDirSync(testingPath, {
maxDepth: Depth.All,
entries: Entry.FilesOnly,
filter: (entry) => entry.path.indexOf('.js') > -1,
})
) // returns only JavaScript - .js files found in all (sub)directories
// Class-based approach
const dir: RecursiveDir = new RecursiveDir()
dir
.maxDepth(Depth.All)
.entries(Entry.FilesOnly)
.filter((entry) => entry.path.indexOf('.md') > -1)
console.log(dir.readDirSync(testingPath)) // returns only .md (Markdown) files found in all (sub)directories📝 Changelog
📑 Read about the latest changes in the CHANGELOG.md.
🪪 License
Licensed under the MIT license.
💖 Support
Consider buying me a coffee. ☕
Thank you for supporting my efforts! 🙏😊
🧬 Related
🥽 Provides ways of parsing UNC paths and checking whether they are valid. 🎱
📜 Formats the provided string as a comment, either a single or a multi line comment for the given programming language. 💻
🥞 Removes HTML code from the given string. Can even extract text-only from the given an HTML string. ✨
🎍 Provides a universal way of formatting file-paths in Unix-like and Windows operating systems as an alternative to the built-in path.normalize(). 🧬
🧰 Determines whether a given value can be a valid file/directory name. 🏜
👨🏻💻 Author
Created by Igor Dimitrijević (@igorskyflyer).