NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #162 most downloaded on npm
The fastest directory crawler & globbing alternative to glob, fast-glob, & tiny-glob. Crawls 1m files in < 1s
Last release 1 years ago
14 Aug 2025
Release timing varies
gaps range from 2 weeks to 9 months
Most releases are documented
notes for 34 of 45 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
45 releases · first in 2020
One column per quarter.
This release brings a lot of cool stuff:
This release brings a lot of cool stuff:
fdir now includes esm builds in addition to the commonjs build.
Thanks to @TheAlexLichter in #147
fdir v6.4.6 broke Node v12 & v14 compatibility as it made use of AbortController. We have now replaced AbortController with an in-house solution that should bring back support for Node v12.
Additionally, fdir now has the engines field set to >=12 to make it super clear what versions of Node we support.
Thanks to @SuperchupuDev & @benmccann for bringing this up and helping me test this!
Huge thanks to @43081j for adding support for this. You can now pass a custom FS module and fdir will make use of it instead of the Node.js fs module.
You can use it like so:
const api = new fdir({
fs: fakeFs,
}).crawl("node_modules");The fs property expects the following methods:
export type FSLike = {
readdir: typeof nativeFs.readdir;
readdirSync: typeof nativeFs.readdirSync;
realpath: typeof nativeFs.realpath;
realpathSync: typeof nativeFs.realpathSync;
stat: typeof nativeFs.stat;
statSync: typeof nativeFs.statSync;
};slice instead of replace when joining path by @SuperchupuDev in #152@types/picomatch v4 by @SuperchupuDev in #156New Contributors
Full Changelog: v6.4.6...v6.5.0
fix: do not stop crawling at currentDepth 0 by @SuperchupuDev in #149
currentDepth 0 by @SuperchupuDev in #149Full Changelog: v6.4.5...v6.4.6
Ensure callback is called only once by @thecodrr in #144
Full Changelog: v6.4.4...v6.4.5
Update documentation for withCallback() by @dave-swift in #133
Full Changelog: v6.4.3...v6.4.4
Do not incorrectly use real paths on exclude predicate by @SuperchupuDev in #129
Fix regression where fdir would never resolve when maxDepth was set to < 0
maxDepth was set to < 0 (#127)Previously, fdir left it up to the OS to handle recursive symlinks. Unfortunately, this resulted in an infinite loop that'd either cause a crash or ta
Previously, fdir left it up to the OS to handle recursive symlinks. Unfortunately, this resulted in an infinite loop that'd either cause a crash or take too long to resolve (each OS has a different limit on resolving recursive symlinks). This has been fixed now in #126.
resolvePaths: trueWhen resolvePaths is set to true, fdir does not crawl a directory it has already visited. To figure out whether we have visited a directory or not, fdir maintains a list of all the directories it has visited. This might result in slightly higher memory usage than before.
For a directory that looks like this:
/dir/
file
symlink -> /dir/
fdir will return:
[ "/dir/file" ]In short, you won't see duplicated paths in the output which is the expected behavior when working with file systems since paths are unique.
resolvePaths: falseWhen you set resolvePaths to false, the behavior differs because now all symlinks become part of the path.
For a directory that looks like this:
/dir/
file
symlink -> /dir/
fdir will return:
[ "/dir/file", "/dir/symlink/file" ]To prevent recursion, all recursive symlinks are only resolved a single level deep making sure you never see something like /dir/symlink/symlink/symlink/file. This allows for glob patterns to work with recursive symlinks without creating a performance issue.
Relative recursive symlinks work exactly as above except the returned paths are relative to the root. Everything else is exactly the same.
Thanks to @SuperchupuDev for bringing this to my attention.
You can now specifically exclude symlinks from the crawling process. Here's how you can do that:
You can now specifically exclude symlinks from the crawling process. Here's how you can do that:
new fdir({ excludeSymlinks: true }).crawl().sync();Thanks to @SuperchupuDev in #115
Previously, fdir only supported picomatch for globbing disallowing any customization in this area. While that worked really well for most people, it wasn't super flexible. Starting from this version, fdir supports changing the default glob function:
// using a custom function
const customGlob = (patterns: string | string[]) => {
return (test: string): boolean => test.endsWith('.js');
};
const crawler = new fdir().withGlobFunction(customGlob).globWithOptions("**/*.js");withGlobFunction accepts a glob factory function which you can use to perform intensive work only once. For example, picomatch provides a glob factory that optimizes and preprocesses your glob patterns increasing match significantly.
fdir by @benmccann in #112New Contributors
Full Changelog: v6.3.0...v6.4.0
withSymlinks now supports the resolvePaths argument again. It was accidentally removed when migrating to TypeScript. Thanks to @SuperchupuDev
withSymlinks now supports the resolvePaths argument again. It was accidentally removed when migrating to TypeScript. Thanks to @SuperchupuDev (https://github.com/thecodrr/fdir/pull/104)withSymlinks is enabled.Full Changelog: https://github.com/thecodrr/fdir/compare/v6.2.0...v6.3.0
withSymlinks now supports the resolvePaths argument again. It was accidentally removed when migrating to TypeScript. Thanks to @SuperchupuDev (#104)withSymlinks is enabled.Full Changelog: v6.2.0...v6.3.0
Updated picomatch peerDependency to v4
picomatch peerDependency to v4onlyDirs is enabled.picomatch peerDependency to v4onlyDirs is enabled.Fixed issue where consecutive backslashes would get collapsed (#93). (This also fixes crawling of WSL directories on Windows which start with \\wsl.lo
\\wsl.localhost\Ubuntu)picomatch peerDependency requirement to 3.x from 2.x.withPathSeparator option allows you enforcing a specific path separator regardless of what platform the code is running on. This is especially useful
withPathSeparator(separator: "/" | "\") 🆕withPathSeparator option allows you enforcing a specific path separator regardless of what platform the code is running on. This is especially useful if your test snapshots contain paths as those snapshots will fail on Windows because Node.js uses \\ path separator on Windows by default.
For example:
const files = await new fdir().withFullPaths().withPathSeparator("/").crawl("node_modules").withPromise();
This release contains a lot of fixes for glob making it much more reliable. (thanks to @bglw for reporting a reproducible test case #92)
This release contains a lot of fixes for glob making it much more reliable. (thanks to @bglw for reporting a reproducible test case #92)
For example, doing this would return an empty array:
const crawler = new fdir().withBasePath().glob("**/*.txt");
const files = await crawler.crawl(".").withPromise();
This was because picomatch and other globbing libraries don't deal too well with paths that start with . or ./. Starting from this version, fdir tries very hard to not include ./ or . at the beginning of the paths.
The end result is that fdir should now work similar to fast-glob and other globbing libraries.
Starting from this version, fdir now officially supports Node v20 with all its tests running on it.
fdir now automatically fallbacks to crawling the current working directory if you pass an empty string as crawl root.withRelativePaths with ./ as root path will now have no effect.Fixed invalid reference of TypeScript types
Full Changelog: https://github.com/thecodrr/fdir/compare/v6.0.0...v6.0.1
> Note: While fdir tries to strictly follow semver, this release doesn't actually break anything. It does deprecate a few things but overall, migratin…
Note: While
fdirtries to strictly follow semver, this release doesn't actually break anything. It does deprecate a few things but overall, migrating from v5.3.0 to v6.0.0 should be seamless.
fdir has now been fully rewritten in TypeScript. This brings better clarity into what's happening and how its happening. The code in the project has also be reorganized & broken down so it's much easier to understand now.
Another benefit of using TypeScript is types. Since everything is now autogenerated by tsc, it is always in sync with the actual API. With the help of generics, the output type is now automatically inferred based on the method used. That means no more as string[] etc.
globWithOptionsGlobbing support has always been barebones in fdir. This release brings in full support for passing picomatch options when globbing. Use it like this:
new fdir()
.globWithOptions(["**/*.js"], { dot: true })
.crawl("path/to/dir")
.sync();
A lot of unintuitive & badly designed API choices have been deprecated. They will continue to work as intended but they will eventually be removed in the upcoming major versions. These include:
crawlWithOptionsThis function was added as a convenience for people who don't like the Builder API. This has now been replaced with the fdir constructor.
Instead of this:
new fdir()
.crawlWithOptions("./", { includeDirs: true })
.sync();
You should now do this:
new fdir({ includeDirs: true })
.crawl("./")
.sync();
P.S. I forgot to deprecate
includeDirsand replace it withincludeDirectories. Oh well, I'll do that in the next version.
directories instead of dirsWhen using the onlyCounts() API, the resulting object will now contain directories instead of dirs. A minor change but I really don't like abbreviations unless absolutely necessary.
directory instead of dirWhen using the group() API, the resulting object will now contain directory instead of dir.
And that's it. No other changes to the API. I am pretty sure that the TypeScript rewrite fixed some hidden & hard-to-debug bugs so you should find v6.0.0 much more stable.
It is now possible to disable path resolution of files inside symlinked directories (#84). This release adds new optional parameter to the withSymlink
withSymlinks. Check the docs on how to use it:This change is 100% backwards compatible and should not break any of your scripts that rely on symlink resolution.
Add picomatch in peerDependencies by @kyleknighted in https://github.com/thecodrr/fdir/pull/76
New Contributors
> Note: fdir follows semantic versoning hence this release is backward compatible with only version 5.x.
Note: fdir follows semantic versoning hence this release is backward compatible with only version 5.x.
withRelativePaths has been added to return paths relative to the root directory (closes #51)Note: fdir follows semantic versoning hence this release is backward compatible with only version 5.x.
Note: fdir follows semantic versoning hence this release is backward compatible with only version 5.x.
.withSymlinks method (#53 & #58):const files = new fdir().withSymlinks().crawl("/path/to/dir").sync();
Aside from the symlinks support, this release has a lot of under-the-hood refactoring. This has improved the maintainability of the project from 83% to 97%.
Major improvements include:
And other changes you can see in PR: #59
Thanks to everyone who has used, supported, tested, & worked on this project. This is also a celebratory release since fdir is now being used by projects such as snowpackjs/snowpack & mdn/yari. So YAY!
_Note: fdir follows semantic versoning hence this release is not backward compatible with any previous release._
Note: fdir follows semantic versoning hence this release is not backward compatible with any previous release.
new fdir().filter() are now joined via AND instead of OR. (#35)onlyDirs builder function that allows you to grab (and filter) only directories ignoring all files. (#43)const crawler = new fdir().onlyDirs();
isDirectory as second parameter to .filter() function:const crawler = new fdir()
.filter((path, isDirectory) => path.startsWith("."))
.filter((path, isDirectory) => path.endsWith(".js"));
excludeFn of .exclude(excludeFn): (#46)const crawler = new fdir().exclude((dirName, dirPath) =>
dirName.startsWith(".")
);
\0 instead of nothing to separate cached glob patterns (#42)ENOENT) occured. (#48)Thank you @papb for your help and PR #45!
## What's Improved: 1. Performance improved by 8%.
Due to issues with export default in the Type Definitions, I had to migrate to using named exports.
export default in the Type Definitions, I had to migrate to using named exports. (#37)So this is now invalid:
import fdir from "fdir";
Instead do this:
import { fdir } from "fdir";
const { fdir } = require("fdir");
Fixed issue where excludeFn was affected by Options (#31) Now fdir only will send the root directory name as the param to excludeFn.
excludeFn was affected by Options (#31) Now fdir only will send the root directory name as the param to excludeFn.Enabled dotfile matching in glob API by default (Fixes: #30)
Nothing published for this version
Multiple filters are now supported. So basically, this will now work as expected:
new fdir().filter(p => p.endsWith(".js")).filter(p => p.startsWith(".nim"))
Install using:
$ npm i fdir
Due to performance reasons, I had to remove passing an Options object through the constructor. In place of that, now there is a new crawlWithOptions t
Options object through the constructor. In place of that, now there is a new crawlWithOptions that takes an Options object in its second parameter:new fdir().crawlWithOptions("path/to/dir", { includeBasePath: true }).sync();
picomatch is not installed.glob performance has been improved by about 40%.
glob performance has been improved by about 40%.It is now possible to pass an Options object directly into the constructor, avoiding method chaining completely.
Options object directly into the constructor, avoiding method chaining completely.withError & crawl.Install using:
npm i fdir
NOTE: This release follows semantic versioning and therefore, it is not backwards compatible with 2.x.
Nothing published for this version
Added a new glob crawler option for glob matching using picomatch. To use it you must install picomatch yourself.
glob crawler option for glob matching using picomatch. To use it you must install picomatch yourself.yarn add picomatch
This was done because not everyone needs globbing.
NOTE: This release is backwards compatible with 3.x
Nothing published for this version
change TypeScript typings to use string instead of String (thanks to @OmgImAlexis)
This is a minor patch release.
string instead of String (thanks to @OmgImAlexis) (#16)Added ignoreErrors option to ignore errors (default: false)
ignoreErrors option to ignore errors (default: false)Options optional in type defs. (#9)This release mainly included bug fixes and code refactoring. Nothing much has changed in terms of performance.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Renamed includeBasePath to excludeBasePath. You'll need to reverse the functionality.
includeBasePath to excludeBasePath. You'll need to reverse the functionality.isExcludedDir function was sending only the directory name (not its path) in the argument. That's fixed now.As always, the performance. Also cleaned up the code quite a lot.
Nothing new. Just optimisations to make it even faster. New benchmarks can be found in README.md
Nothing new. Just optimisations to make it even faster. New benchmarks can be found in README.md
Nothing published for this version
Nothing published for this version
Migrated to util.promisify for fdir.async. This surprisingly improves performance on battery (when CPU is downclocked to save battery) so now both ben
Nothing
Migrated to util.promisify for fdir.async. This surprisingly improves performance on battery (when CPU is downclocked to save battery) so now both benchmarks are almost equal.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →