686f6c61/minimatch-fast
v0.4.0 live on npm

minimatch-fast

Drop-in replacement for minimatch.
Up to 36x faster. Zero vulnerabilities.

npm install minimatch-fast
  • picomatch engine
  • 100% API compatible
  • TypeScript
  • ESM + CJS
  • 402 tests

MIT License

features

Why minimatch-fast?

The performance and security upgrade your glob matching needs

Lightning Fast

up to 36x faster than minimatch. Powered by picomatch engine with LRU caching and optimized fast paths for common patterns.

Secure

Not vulnerable to CVE-2022-3517 (ReDoS). Built-in protection against catastrophic backtracking and DoS attacks.

Stable

Never freezes on patterns like {1..1000}. Limits on brace expansion prevent hanging or memory issues.

100% Compatible

Drop-in replacement with identical API. 402 tests ensure full compatibility with minimatch v10.x behavior.

TypeScript Ready

Full TypeScript support with complete type definitions included. No need to install separate @types packages.

Dual Module Support

Works with both ESM and CommonJS. Use import or require() - we support both module systems out of the box.

benchmark

Performance Benchmarks

Every scenario beats minimatch v10.x — 3 stable consecutive runs, median of 21 rounds, 1000-path corpus

Real-world globbing (warm LRU cache)

The real glob workload: build tools and linters match a handful of patterns against thousands of files. minimatch recompiles on every call; minimatch-fast caches compiled patterns. This asymmetry is an openly acknowledged product feature.

Patternminimatchminimatch-fastSpeedup
{src,lib}/**/*.{js,ts,tsx}88.0ms2.4ms36x faster
@(foo|bar|baz).js~190x faster
*.js~64x faster
**/*.js4.3x faster

The big numbers come from early rejection: slashless patterns are rejected without compiling for nested paths, because one segment cannot cross /.

Engine vs engine (pre-compiled, no cache)

The most honest comparison: the same pre-compiled pattern on both sides, no cache involved. The engine wins 2.4-12x on every measured pattern shape.

Patternminimatchminimatch-fast
file[0-9].jsBaseline12x faster
@(foo|bar|baz).jsBaseline12x faster
*.js / !*.test.js / ???.jsBaseline8-9x faster
{src,lib}/**/*.{js,ts,tsx}Baseline3.4x faster
**/*.js / **/**/**/*.jsBaseline2.7x faster
{src,lib}/*.jsBaseline2.4x faster

Compilation and cold calls

The worst-case workload: one-off calls where every pattern gets compiled. Even there, always above parity.

Scenariominimatchminimatch-fast
Compile {src,lib}/**/*.{js,ts,tsx}Baseline5.7x faster
Compile @(foo|bar|baz).js (extglob)Baseline3x faster
Compile *.js / **/*.jsBaseline1.6-2.3x faster
Cold @(foo|bar|baz).js (extglob)Baseline~105x faster
Cold *.jsBaseline~20x faster
Cold complex bracesBaseline~4x faster
Cold **/*.jsBaseline1.1-1.9x faster

Security Comparison

Featureminimatchminimatch-fast
CVE-2022-3517 (ReDoS)VulnerableNot affected
Pattern {1..1000}FreezesInstant
Brace expansion limitNone10,000 max

Node.js 22, Linux. Methodology: interleaved A/B/B/A, 5 warmup rounds, median of 21 rounds, 1000-path deterministic corpus, 3 stable consecutive runs. Reproduce with npm run benchmark.

install

Installation

Two ways to upgrade from minimatch

option 1 Update imports

Install the package and update your import statements:

Terminal
npm uninstall minimatch
npm install minimatch-fast

Then update your imports:

- const minimatch = require('minimatch');
+ const minimatch = require('minimatch-fast');
- import minimatch from 'minimatch';
+ import minimatch from 'minimatch-fast';

option 2 npm aliasing

Zero code changes required. Use npm's package aliasing:

Terminal
npm install minimatch@npm:minimatch-fast

This installs minimatch-fast as minimatch, so all your existing imports continue to work without any changes.

Note: This also updates minimatch for all your dependencies that use it.
usage

Usage Examples

Common patterns and use cases

Basic Matching

javascript
import minimatch from 'minimatch-fast';

// Basic matching
minimatch('foo.js', '*.js');    // true
minimatch('bar.txt', '*.js');   // false

// Globstar (recursive)
minimatch('src/utils/helpers.js', '**/*.js');  // true
minimatch('test/foo/bar.spec.ts', '**/*.ts');  // true

Match Array

javascript
import { minimatch } from 'minimatch-fast';

const files = ['foo.js', 'bar.js', 'baz.txt', 'qux.md'];

// Match array of files
minimatch.match(files, '*.js');
// => ['foo.js', 'bar.js']

minimatch.match(files, '*.{js,md}');
// => ['foo.js', 'bar.js', 'qux.md']

Filter Function

javascript
import { minimatch } from 'minimatch-fast';

const files = ['src/index.js', 'src/utils.js', 'test/foo.spec.js'];

// Create a filter function
const isSource = minimatch.filter('src/**/*.js');

files.filter(isSource);
// => ['src/index.js', 'src/utils.js']

Minimatch Class

javascript
import { Minimatch } from 'minimatch-fast';

// Pre-compile pattern for repeated matching
const mm = new Minimatch('**/*.js', { dot: true });

// Match multiple files efficiently
mm.match('src/index.js');     // true
mm.match('.eslintrc.js');     // true (dot: true)
mm.match('README.md');        // false

// Access the compiled regex
console.log(mm.regexp);       // /^(?:(?!...)...$/

Brace Expansion

javascript
import { minimatch } from 'minimatch-fast';

// Brace expansion
minimatch.braceExpand('{a,b,c}');
// => ['a', 'b', 'c']

minimatch.braceExpand('{1..5}');
// => ['1', '2', '3', '4', '5']

minimatch.braceExpand('file{A,B}.{js,ts}');
// => ['fileA.js', 'fileA.ts', 'fileB.js', 'fileB.ts']

Escape / Unescape

javascript
import { minimatch } from 'minimatch-fast';

// Escape special characters
minimatch.escape('[foo].js');
// => '\\[foo\\].js'

// Unescape
minimatch.unescape('\\[foo\\].js');
// => '[foo].js'
patterns

Glob Pattern Reference

Complete guide to glob pattern syntax

PatternDescriptionExample
*Match any characters except path separators*.js matches foo.js, bar.js
**Match any characters including path separators (globstar)**/*.js matches src/foo.js, a/b/c.js
?Match exactly one character (except path separator)?.js matches a.js, b.js
[abc]Match any character in the set[abc].js matches a.js, b.js, c.js
[a-z]Match any character in the range[a-z].js matches a.js through z.js
[!abc]Match any character NOT in the set[!a].js matches b.js, c.js (not a.js)
{a,b,c}Match any of the comma-separated patterns{foo,bar}.js matches foo.js, bar.js
{1..5}Match numeric rangefile{1..3}.js matches file1.js, file2.js, file3.js
{a..c}Match alphabetic range{a..c}.js matches a.js, b.js, c.js
!patternNegate the match!*.min.js excludes minified files
?(a|b)Match zero or one of the patterns?(foo).js matches .js, foo.js
*(a|b)Match zero or more of the patterns*(a|b).js matches .js, a.js, ab.js, aab.js
+(a|b)Match one or more of the patterns+(a|b).js matches a.js, ab.js, aab.js
@(a|b)Match exactly one of the patterns@(foo|bar).js matches foo.js, bar.js

POSIX Character Classes

Full support for POSIX bracket expressions

ClassDescriptionExample
[[:alpha:]]Alphabetic characters (a-z, A-Z)[[:alpha:]]*.txt matches file.txt
[[:digit:]]Numeric digits (0-9)file[[:digit:]].js matches file1.js
[[:alnum:]]Alphanumeric (letters and digits)[[:alnum:]] matches a, Z, 5
[[:space:]]Whitespace characters[[:space:]] matches space, tab
[[:upper:]]Uppercase letters[[:upper:]] matches A but not a
[[:lower:]]Lowercase letters[[:lower:]] matches a but not A
[[:xdigit:]]Hexadecimal digits (0-9, a-f, A-F)[[:xdigit:]] matches 0, a, F

Unicode Support

Full Unicode and emoji support in patterns and filenames

PatternDescriptionMatches
*.txtFull Unicode support in filenamescafé.txt, 文件.txt, ファイル.txt
文件夹/*.jsUnicode in patterns文件夹/test.js matches
{🎉,🎊}.txtEmoji support🎉.txt, 🎊.txt
api

API Reference

Complete API documentation

minimatch(path, pattern, [options])

Test a path against a pattern. Returns true if the path matches.

Parameters

  • pathstringThe path to test
  • patternstringThe glob pattern
  • optionsMinimatchOptionsOptional configuration

Returns

boolean

Example

minimatch('foo.js', '*.js'); // true
minimatch('foo/bar.js', '**/*.js'); // true
minimatch.match(list, pattern, [options])

Filter an array of paths, returning those that match the pattern.

Parameters

  • liststring[]Array of paths to filter
  • patternstringThe glob pattern
  • optionsMinimatchOptionsOptional configuration

Returns

string[]

Example

const files = ['a.js', 'b.ts', 'c.js'];
minimatch.match(files, '*.js');
// => ['a.js', 'c.js']
minimatch.filter(pattern, [options])

Create a filter function for use with Array.filter().

Parameters

  • patternstringThe glob pattern
  • optionsMinimatchOptionsOptional configuration

Returns

(path: string) => boolean

Example

const isJS = minimatch.filter('*.js');
['a.js', 'b.ts'].filter(isJS);
// => ['a.js']
minimatch.makeRe(pattern, [options])

Create a regular expression from the pattern.

Parameters

  • patternstringThe glob pattern
  • optionsMinimatchOptionsOptional configuration

Returns

RegExp | false

Example

minimatch.makeRe('*.js');
// => /^(?:(?!\.)...)\.js$/
minimatch.braceExpand(pattern, [options])

Expand brace patterns into an array of patterns.

Parameters

  • patternstringPattern with braces
  • optionsMinimatchOptionsOptional configuration

Returns

string[]

Example

minimatch.braceExpand('{a,b}{1,2}');
// => ['a1', 'a2', 'b1', 'b2']
minimatch.escape(str, [options])

Escape special glob characters in a string.

Parameters

  • strstringString to escape
  • options{ windowsPathsNoEscape?: boolean }Optional configuration

Returns

string

Example

minimatch.escape('[foo].js');
// => '\\[foo\\].js'
minimatch.unescape(str, [options])

Remove escape characters from a string.

Parameters

  • strstringString to unescape
  • options{ windowsPathsNoEscape?: boolean }Optional configuration

Returns

string

Example

minimatch.unescape('\\[foo\\].js');
// => '[foo].js'
minimatch.defaults(options)

Create a new minimatch function with default options.

Parameters

  • optionsMinimatchOptionsDefault options to apply

Returns

typeof minimatch

Example

const mm = minimatch.defaults({ nocase: true });
mm('FOO.js', '*.js'); // true
new Minimatch(pattern, [options])

Create a reusable matcher for a pattern. More efficient when matching the same pattern against multiple paths.

Parameters

  • patternstringThe glob pattern
  • optionsMinimatchOptionsOptional configuration

Returns

Minimatch

Example

const mm = new Minimatch('**/*.js');
mm.match('src/foo.js'); // true
mm.match('test/bar.js'); // true
options

Options

Configuration options for fine-tuning pattern matching

Core Options minimatch compatible

OptionTypeDefaultDescription
dotbooleanfalseMatch dotfiles (files starting with .). By default, * and ? do not match leading dots.
nocasebooleanfalsePerform case-insensitive matching.
nonegatebooleanfalseSuppress negation behavior with leading !.
nobracebooleanfalseDo not expand brace patterns like {a,b,c}.
noextbooleanfalseDisable extglob patterns like ?(a|b), *(a|b), etc.
noglobstarbooleanfalseDisable ** matching across directory boundaries.
nocommentbooleanfalseSuppress treating # as a comment character.
matchBasebooleanfalseIf pattern has no slashes, match basename of the path. foo matches bar/baz/foo.
partialbooleanfalsePartial match: pattern can match a portion of the path.
flipNegatebooleanfalseReturns true for negated patterns that do not match.
preserveMultipleSlashesbooleanfalseDo not collapse multiple slashes (a//b stays as a//b).
optimizationLevelnumber1Regex optimization level: 0 = none, 1 = safe (default), 2 = aggressive.
platformstringprocess.platformPlatform for path handling: "win32", "darwin", "linux", etc.
windowsPathsNoEscapebooleanfalseOn Windows, treat \ as path separator, not escape character.
allowWindowsEscapebooleanplatform !== "win32"Allow \ as escape character on Windows.
nocaseMagicOnlybooleanfalseOnly apply nocase to magic portions of the pattern.
magicalBracesbooleanfalseTreat brace expansion as magic (affects hasMagic()).
debugbooleanfalseEnable debug output.

Extended Options new in v0.3.0

OptionTypeDefaultDescription
ignorestring | string[]undefinedPatterns to exclude from matching.
failglobbooleanfalseThrow error if no matches found (takes precedence over nonull).
maxLengthnumber65536Maximum pattern length. Prevents ReDoS attacks.
expandRangefunctionundefinedCustom function for expanding ranges in brace patterns.
bashbooleanfalseFollow bash matching rules more strictly.
containsbooleanfalseMatch pattern anywhere in string (not just full match).
formatfunctionundefinedCustom function for formatting strings before matching.
flagsstringundefinedRegex flags to use in generated regex.
strictBracketsbooleanfalseThrow error if brackets, braces, or parens are imbalanced.
literalBracketsbooleanfalseEscape brackets to match literal [ and ].
keepQuotesbooleanfalseRetain quotes in the generated regex.
unescapebooleanfalseRemove backslashes preceding escaped characters.

Callback Options new in v0.3.0

OptionTypeDefaultDescription
onMatchfunctionundefinedCalled when a pattern matches. Receives match result object.
onIgnorefunctionundefinedCalled when a pattern is ignored. Receives match result object.
onResultfunctionundefinedCalled for all results. Receives match result object.

Examples

ignore

const mm = new Minimatch('**/*.js', {
  ignore: ['**/*.test.js', '**/node_modules/**']
});
mm.match('src/app.js');      // true
mm.match('src/app.test.js'); // false

failglob

// Throw if no matches found
minimatch.match(files, '*.ts', { failglob: true });
// Error: No matches found for pattern: *.ts

contains

// Match anywhere in string
minimatch('foobar', 'bar', { contains: true });
// true (matches substring)

format

// Transform paths before matching
const mm = new Minimatch('src/*.js', {
  format: (s) => s.replace(/^\.\//, '')
});
mm.match('./src/app.js'); // true

callbacks

const mm = new Minimatch('*.js', {
  onMatch: (r) => console.log('Match:', r.output),
  onResult: (r) => stats[r.isMatch ? 'hits' : 'miss']++
});

literalBrackets

// Match literal brackets in filenames
const mm = new Minimatch('[file].js', {
  literalBrackets: true
});
mm.match('[file].js'); // true
security

Security

Built-in protection against common vulnerabilities

CVE-2022-3517 Protection

The original minimatch is vulnerable to Regular Expression Denial of Service (ReDoS) via CVE-2022-3517. Malicious patterns can cause catastrophic backtracking, freezing your application.

minimatch-fast uses picomatch internally, which is specifically designed to avoid backtracking issues and is not vulnerable to this CVE.

javascript
// CVE-2022-3517 - Vulnerable pattern in minimatch
// This causes catastrophic backtracking (ReDoS)
const pattern = '[!' + 'a'.repeat(50000) + ']';

// In minimatch: hangs for minutes or crashes
minimatch('test', pattern);

// In minimatch-fast: instant, no vulnerability
minimatch('test', pattern); // false, returns immediately

Brace Expansion Limits

Unconstrained brace expansion can be exploited to create denial of service attacks. A pattern like {1..1000000} would generate a million patterns, consuming all available memory.

minimatch-fast limits brace expansion to 10,000 patterns maximum and range expansion to 1,000 items, preventing DoS attacks.

javascript
// Dangerous brace expansion in minimatch
// This creates 1,000,000 patterns and freezes

const pattern = '{1..1000000}';
minimatch.braceExpand(pattern); // Hangs

// In minimatch-fast: limited to 10,000 max
// Returns original pattern if limit exceeded

Input Validation

The original minimatch accepts invalid inputs that can cause unexpected behavior or runtime errors deep in the call stack.

minimatch-fast validates both path and pattern arguments upfront, throwing descriptive TypeErrors immediately. Pattern length is also limited to prevent DoS.

javascript
// minimatch-fast validates input types
// Prevents runtime errors and unexpected behavior

minimatch(null, '*.js');      // TypeError: path must be a string
minimatch('test', undefined); // TypeError: glob pattern must be a string
minimatch(123, '*.js');       // TypeError: path must be a string

// Pattern length limits prevent DoS
const veryLong = 'a'.repeat(100000);
minimatch('test', veryLong);  // TypeError: pattern too long

Security Features

  • Not affected by CVE-2022-3517 (ReDoS)
  • Maximum 10,000 patterns from brace expansion
  • Maximum 1,000 items in range expansion ({1..N})
  • No catastrophic backtracking in regex
  • Graceful fallback for oversized patterns
  • Input type validation for path and pattern
  • Pattern length limits (max 65,536 characters)
typescript

TypeScript Support

Full type definitions included

minimatch-fast ships with complete TypeScript definitions. All types are exported and ready to use without installing separate @types packages.

typescript
import minimatch, {
  Minimatch,
  MinimatchOptions,
  MMRegExp
} from 'minimatch-fast';

// Options with full type support
const options: MinimatchOptions = {
  dot: true,
  nocase: true,
  noglobstar: false
};

// Basic matching
const matches: boolean = minimatch('foo.js', '*.js', options);

// Minimatch class
const mm: Minimatch = new Minimatch('**/*.ts', options);
const isMatch: boolean = mm.match('src/index.ts');

// Get the compiled regex
const regex: MMRegExp | false = mm.makeRe();

// Filter function
const filter: (p: string) => boolean = minimatch.filter('*.js');

// Match array
const files: string[] = minimatch.match(['a.js', 'b.ts'], '*.js');

// Brace expansion
const expanded: string[] = minimatch.braceExpand('{a,b,c}');

Exported Types

  • minimatch - The main function
  • Minimatch - The Minimatch class
  • MinimatchOptions - Configuration options interface
  • MMRegExp - Extended RegExp with index info
  • ParseReturn - Type for parsed pattern segments
  • AST - Type for the abstract syntax tree
tests

Testing & Compatibility

Comprehensive test suite ensures reliability

42
Unit Tests
Core functionality tests
196
Compatibility Tests
Behavior parity with minimatch
64
Edge Case Tests
Windows paths, extended options, dotfiles
23
Security Tests
CVE-2022-3517 and input validation tests
53
Verification Tests
POSIX classes, Unicode, regex edge cases
24
Regression Tests
Cache correctness, hasMagic, makeRe, escape alignment

402 tests total

Every release is verified against the original minimatch test suite plus additional tests for edge cases, Windows paths, and security vulnerabilities.

Running Tests

bash
# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Run compatibility tests only
npm run test:compat

Reporting Issues

Found a compatibility issue? Please open an issue on GitHub with:

  • The pattern and path that produces different results
  • Expected behavior (what minimatch returns)
  • Actual behavior (what minimatch-fast returns)
  • Any relevant options used
changelog

Changelog

Project evolution and version history

v0.4.0Current
20/07/2026
  • Cache correctness fixes
  • hasMagic() and makeRe() parity with minimatch
  • escape/unescape 1:1 alignment
  • 402 tests
  • fixedCache key now includes every matching-affecting option (contains, bash, flags, ignore, maxLength, strictBrackets, literalBrackets, keepQuotes, unescape, magicalBraces)
  • fixedhasMagic() returns false for literal patterns, matching minimatch
  • fixedmakeRe() honors negated patterns (!*.js), matching minimatch
  • fixednonull option no longer leaks between calls through the pattern cache
  • changedescape()/unescape() aligned 1:1 with minimatch: braces only escaped with magicalBraces: true
  • changedFast paths fall back to the full engine when options they cannot honor are present
  • securitymaxLength is now also enforced before fast-path matching
  • securityReleases published via npm trusted publishing (OIDC) with Sigstore provenance
  • added24 new regression tests (402 total)
v0.3.0
01/02/2026
  • 15 new picomatch options
  • Callback support
  • Better error messages
  • 378 tests
  • addedExtended picomatch options: ignore, failglob, maxLength, expandRange, bash, contains, format, flags
  • addedBracket options: strictBrackets, literalBrackets, keepQuotes, unescape
  • addedCallback options: onMatch, onIgnore, onResult
  • changedImproved maxLength error messages with pattern length and limit details
  • changedfailglob now shows how many paths were searched
  • securitymaxLength now validates for positive finite numbers
  • added22 new tests for extended options
v0.2.3
01/02/2026
  • Input validation for path
  • Clean code improvements
  • Dead code removal
  • 356 tests
  • securityAdded type validation for path parameter in minimatch()
  • changedFixed generic error message to descriptive message
  • removedRemoved console.warn from library code
  • removedRemoved dead code (hasMagicChars, escapeRegex, hasBraces)
  • changedConsistent operators (?? instead of || for defaults)
  • addedTests for path validation (5 cases)
v0.2.2
31/01/2026
  • Security audit
  • Dependency updates
  • Clean code review
  • securitySecurity audit completed
  • changedUpdated dependencies
  • changedClean code improvements
v0.2.1
19/01/2026
  • Pattern length validation
  • Landing page
  • Benchmarks
  • securityAdded pattern length validation (max 65,536 chars)
  • addedLanding page with documentation
  • addedBenchmark suite comparing with original minimatch
v0.2.0
29/12/2025
9.4x faster average
  • LRU pattern cache (500 entries)
  • Fast paths for simple patterns
  • Brace expansion cache (200 entries)
  • Cache utility functions
  • addedPattern cache for compiled Minimatch instances
  • addedFast paths for *, *.js, ???, .* patterns
  • addedBrace expansion cache
  • addedclearCache() and getCacheSize() utilities
  • changedPre-computed regex flags in Minimatch class
  • changedOptimized basename extraction
  • changedSmarter Windows path normalization
v0.1.0Initial Release
10/11/2025
7-29x faster
  • 100% API compatible with minimatch
  • Powered by picomatch engine
  • Full TypeScript support
  • Dual ESM/CJS exports
  • addedInitial release of minimatch-fast
  • added100% API compatibility with minimatch v10.x
  • addedFull TypeScript support with type definitions
  • addedDual ESM and CommonJS module exports
  • addedComprehensive test suite (302 tests)
  • addedGitHub Actions CI/CD pipeline
  • securityNot affected by CVE-2022-3517 (ReDoS)
  • securityLimits on brace expansion to prevent DoS