Async and recursive directory scan, for file listing in Nodejs and Expressjs
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Recursive file listing is a common backend task in Node.js applications. You may need it to build an asset browser, expose downloadable files through Express, or scan user-uploaded content without blocking the event loop.
The key design goal is to walk the directory tree asynchronously. That keeps the server responsive while the filesystem work is in progress and avoids tying up the process with synchronous I/O.
A Basic Async Recursive Scanner
In modern Node.js, the cleanest approach uses fs.promises with async and await. The function below walks a directory tree and returns relative file paths:
This version is simple and predictable. It descends into every subdirectory and collects only files.
Exposing The Result Through Express
Once the scanner works, returning the list from an Express route is straightforward:
The route handler is asynchronous, so filesystem latency does not freeze the server. The request simply waits for the promise to resolve.
Concurrency Versus Safety
The previous scanner walks one directory at a time. That is often enough and is easier to debug. If the tree is very large, you can add limited concurrency with Promise.all, but do it carefully so you do not create too many simultaneous filesystem operations.
A simple concurrent variant looks like this:
This is faster on some directory trees, but it also fans out aggressively. For very large trees, consider a queue with controlled concurrency instead of unlimited parallel recursion.
Security And Path Handling
In Express applications, directory scanning should not blindly trust user input. If a route accepts a folder name from the client, resolve it against an allowed base directory and reject traversal attempts.
For example, normalize the requested path and verify that the resolved absolute path still starts with your permitted root. Without that check, a crafted path could escape the intended directory tree.
Common Pitfalls
The most common mistake is using synchronous APIs such as fs.readdirSync inside request handlers. That blocks the event loop and hurts throughput under concurrent traffic.
Another pitfall is forgetting to handle symlinks. A symlink can point outside the expected tree or even create a recursive loop. If your application must traverse symlinks, decide on explicit rules and track visited targets.
A third issue is returning absolute filesystem paths directly to clients. Those paths can leak internal server structure. Relative paths or logical file identifiers are safer for API responses.
Summary
- Use
fs.promiseswithasyncandawaitfor recursive directory scans in Node.js. - The parent Express route can await the scan without blocking the event loop.
- Sequential recursion is simpler; concurrent recursion can be faster but needs limits.
- Validate any user-controlled path before scanning directories.
- Avoid sync filesystem APIs in request handlers.
Related reading
- Async API endpoint Spring Webflux
- Async Aspect AfterReturnung. My method has HttpServletRequest object as method argument, but able to access it my aop method
- Async await and event handler
- Async await and parallel
- Async await sqlite in javascript
- Async call in ember testing
- Async, await and Task with ToList
- async await blocking ui wp8
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.