
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
Recursive version of fs.readdir. Exposes a stream API (with small RAM & CPU footprint) and a promise API.
npm install readdirp
jsr add jsr:@paulmillr/readdirp
// Use streams to achieve small RAM & CPU footprint.
// 1) Streams example with for-await.
import readdirp from 'readdirp';
for await (const entry of readdirp('.')) {
const {path} = entry;
console.log(`${JSON.stringify({path})}`);
}
// 2) Streams example, non for-await.
// Print out all JS files along with their size within the current folder & subfolders.
import readdirp from 'readdirp';
readdirp('.', {alwaysStat: true, fileFilter: (f) => f.basename.endsWith('.js')})
.on('data', (entry) => {
const {path, stats: {size}} = entry;
console.log(`${JSON.stringify({path, size})}`);
})
// Optionally call stream.destroy() in `warn()` in order to abort and cause 'close' to be emitted
.on('warn', error => console.error('non-fatal error', error))
.on('error', error => console.error('fatal error', error))
.on('end', () => console.log('done'));
// 3) Promise example. More RAM and CPU than streams / for-await.
import { readdirpPromise } from 'readdirp';
const files = await readdirpPromise('.');
console.log(files.map(file => file.path));
// Other options.
import readdirp from 'readdirp';
readdirp('test', {
fileFilter: (f) => f.basename.endsWith('.js'),
directoryFilter: (d) => d.basename !== '.git',
// directoryFilter: (di) => di.basename.length === 9
type: 'files_directories',
depth: 1
});
const stream = readdirp(root[, options]) — Stream API
stream of entry infosfor await (const entry of stream) with node.js 10+ (asyncIterator).on('data', (entry) => {}) entry info for every file / dir.on('warn', (error) => {}) non-fatal Error that prevents a file / dir from being processed. Example: inaccessible to the user.on('error', (error) => {}) fatal Error which also ends the stream. Example: illegal options where passed.on('end') — we are done. Called when all entries were found and no more will be emitted.on('close') — stream is destroyed via stream.destroy().
Could be useful if you want to manually abort even on a non fatal error.
At that point the stream is no longer readable and no more entries, warning or errors are emittedconst entries = await readdirp.promise(root[, options]) — Promise API. Returns a list of entry infos.
First argument is awalys root, path in which to start reading and recursing into subdirectories.
fileFilter: filter to include or exclude files
directoryFilter: filter to include/exclude directories found and to recurse into. Directories that do not pass a filter will not be recursed into.depth: 5: depth at which to stop recursing even if more subdirectories are foundtype: 'files': determines if data events on the stream should be emitted for 'files' (default), 'directories', 'files_directories', or 'all'. Setting to 'all' will also include entries for other types of file descriptors like character devices, unix sockets and named pipes.alwaysStat: false: always return stats property for every file. Default is false, readdirp will return Dirent entries. Setting it to true can double readdir execution time - use it only when you need file size, mtime etc. Cannot be enabled on node <10.10.0.lstat: false: include symlink entries in the stream along with files. When true, fs.lstat would be used instead of fs.statEntryInfoHas the following properties:
path: 'assets/javascripts/react.js': path to the file/directory (relative to given root)fullPath: '/Users/dev/projects/app/assets/javascripts/react.js': full path to the file/directory foundbasename: 'react.js': name of the file/directorydirent: fs.Dirent: built-in dir entry object - only with alwaysStat: falsestats: fs.Stats: built in stat object - only with alwaysStat: truelet {readdirp} = require('readdirp') in common.jshighWaterMark option. Fixes race conditions related to for-await looping.bigint support to stat output on Windows. This is backwards-incompatible for some cases. Be careful. It you use it incorrectly, you'll see "TypeError: Cannot mix BigInt and other types, use explicit conversions".readdirp(options) to readdirp(root, options)entryType option to typeentryType: 'both' to 'files_directories'EntryInfo
stat to stats
alwaysStat: truedirent is emitted instead of stats by default with alwaysStat: falsename to basenameparentDir and fullParentDir propertiesCopyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com)
MIT License, see LICENSE file.
The 'glob' package provides pattern matching functionality to select files in directories. It's similar to readdirp in that it can be used to search for files, but it uses glob patterns instead of providing a stream API or Promise-based interface.
The 'fs-extra' package extends the built-in Node.js 'fs' module with additional file system methods, including recursive directory reading. While it offers similar functionality to readdirp, fs-extra provides a broader set of file system operations, making it more of a general-purpose library.
The 'walk' package is another Node.js module for recursively reading directory contents. It is similar to readdirp but focuses more on event-based directory walking. Compared to readdirp, 'walk' might offer a simpler API for some use cases but lacks the advanced filtering and mapping capabilities.
FAQs
Recursive version of fs.readdir with small RAM & CPU footprint
The npm package readdirp receives a total of 124,056,472 weekly downloads. As such, readdirp popularity was classified as popular.
We found that readdirp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.