Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.
npx @tessl/cli install tessl/npm-picomatch@4.0.0Picomatch is a blazing fast and accurate glob matcher written in JavaScript with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.
npm install picomatchconst picomatch = require('picomatch');ES Modules:
import picomatch from 'picomatch';For POSIX-only usage:
const picomatch = require('picomatch/posix');const picomatch = require('picomatch');
// Create a matcher function
const isMatch = picomatch('*.js');
console.log(isMatch('file.js')); // => true
console.log(isMatch('file.txt')); // => false
// Multiple patterns
const isMatchAny = picomatch(['*.js', '*.ts']);
console.log(isMatchAny('app.ts')); // => true
// With options
const matcher = picomatch('**/*.js', { ignore: '**/node_modules/**' });
console.log(matcher('src/utils.js')); // => true
console.log(matcher('node_modules/lib.js')); // => falsePicomatch is built around several key components:
Primary matcher function creation and pattern matching capabilities. The main entry point for creating efficient matcher functions from glob patterns.
/**
* Creates a matcher function from one or more glob patterns
* @param {string|string[]} glob - Glob pattern(s) to compile
* @param {object} options - Configuration options
* @param {boolean} returnState - Whether to return state information
* @returns {function} Matcher function that tests strings
*/
function picomatch(glob, options, returnState = false);Direct pattern testing without creating persistent matcher functions. Useful for one-off matching operations.
/**
* Test input with the given regex
* @param {string} input - String to test
* @param {RegExp} regex - Regular expression to test against
* @param {object} options - Configuration options
* @param {object} context - Additional context (glob, posix)
* @returns {object} Object with matching info
*/
picomatch.test(input, regex, options, { glob, posix });
/**
* Returns true if any of the given patterns match the string
* @param {string} str - String to test
* @param {string|string[]} patterns - Glob pattern(s) to test
* @param {object} options - Configuration options
* @returns {boolean} True if any patterns match
*/
picomatch.isMatch(str, patterns, options);Low-level pattern parsing and regex compilation utilities for advanced use cases and custom implementations.
/**
* Parse a glob pattern to create source string for regex
* @param {string|string[]} pattern - Glob pattern(s) to parse
* @param {object} options - Configuration options
* @returns {object|object[]} Parsed pattern object(s)
*/
picomatch.parse(pattern, options);
/**
* Create a regular expression from glob pattern
* @param {string} input - Glob pattern
* @param {object} options - Configuration options
* @param {boolean} returnOutput - Return output instead of regex
* @param {boolean} returnState - Include state in result
* @returns {RegExp} Compiled regular expression
*/
picomatch.makeRe(input, options, returnOutput, returnState);Access to internal constants and utility functions for advanced use cases.
/**
* Internal constants used by picomatch
*/
picomatch.constants: {
/** Maximum length for glob patterns */
MAX_LENGTH: 65536;
/** POSIX bracket expressions */
POSIX_REGEX_SOURCE: {
alnum: string;
alpha: string;
ascii: string;
blank: string;
cntrl: string;
digit: string;
graph: string;
lower: string;
print: string;
punct: string;
space: string;
upper: string;
word: string;
xdigit: string;
};
/** Regular expressions for parsing */
REGEX_BACKSLASH: RegExp;
REGEX_NON_SPECIAL_CHARS: RegExp;
REGEX_SPECIAL_CHARS: RegExp;
REGEX_SPECIAL_CHARS_BACKREF: RegExp;
REGEX_SPECIAL_CHARS_GLOBAL: RegExp;
REGEX_REMOVE_BACKSLASH: RegExp;
/** Pattern replacements for optimization */
REPLACEMENTS: {
'***': '*';
'**/**': '**';
'**/**/**': '**';
};
/** Character code constants */
CHAR_0: 48;
CHAR_9: 57;
CHAR_UPPERCASE_A: 65;
CHAR_LOWERCASE_A: 97;
CHAR_UPPERCASE_Z: 90;
CHAR_LOWERCASE_Z: 122;
CHAR_LEFT_PARENTHESES: 40;
CHAR_RIGHT_PARENTHESES: 41;
CHAR_ASTERISK: 42;
CHAR_AMPERSAND: 38;
CHAR_AT: 64;
CHAR_BACKWARD_SLASH: 92;
CHAR_CARRIAGE_RETURN: 13;
CHAR_CIRCUMFLEX_ACCENT: 94;
CHAR_COLON: 58;
CHAR_COMMA: 44;
CHAR_DOT: 46;
CHAR_DOUBLE_QUOTE: 34;
CHAR_EQUAL: 61;
CHAR_EXCLAMATION_MARK: 33;
CHAR_FORM_FEED: 12;
CHAR_FORWARD_SLASH: 47;
CHAR_GRAVE_ACCENT: 96;
CHAR_HASH: 35;
CHAR_HYPHEN_MINUS: 45;
CHAR_LEFT_ANGLE_BRACKET: 60;
CHAR_LEFT_CURLY_BRACE: 123;
CHAR_LEFT_SQUARE_BRACKET: 91;
CHAR_LINE_FEED: 10;
CHAR_NO_BREAK_SPACE: 160;
CHAR_PERCENT: 37;
CHAR_PLUS: 43;
CHAR_QUESTION_MARK: 63;
CHAR_RIGHT_ANGLE_BRACKET: 62;
CHAR_RIGHT_CURLY_BRACE: 125;
CHAR_RIGHT_SQUARE_BRACKET: 93;
CHAR_SEMICOLON: 59;
CHAR_SINGLE_QUOTE: 39;
CHAR_SPACE: 32;
CHAR_TAB: 9;
CHAR_UNDERSCORE: 95;
CHAR_VERTICAL_LINE: 124;
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279;
/** Create extglob character definitions */
extglobChars: (chars: object) => {
'!': { type: 'negate'; open: string; close: string };
'?': { type: 'qmark'; open: string; close: string };
'+': { type: 'plus'; open: string; close: string };
'*': { type: 'star'; open: string; close: string };
'@': { type: 'at'; open: string; close: string };
};
/** Create glob character definitions for platform */
globChars: (win32: boolean) => {
DOT_LITERAL: string;
PLUS_LITERAL: string;
QMARK_LITERAL: string;
SLASH_LITERAL: string;
ONE_CHAR: string;
QMARK: string;
END_ANCHOR: string;
DOTS_SLASH: string;
NO_DOT: string;
NO_DOTS: string;
NO_DOT_SLASH: string;
NO_DOTS_SLASH: string;
QMARK_NO_DOT: string;
STAR: string;
START_ANCHOR: string;
SEP: string;
};
}interface PicomatchOptions {
/** Force Windows-style path handling */
windows?: boolean;
/** Patterns to ignore */
ignore?: string | string[];
/** Callback for match events */
onMatch?: (result: MatchResult) => void;
/** Callback for all results */
onResult?: (result: MatchResult) => void;
/** Callback for ignored matches */
onIgnore?: (result: MatchResult) => void;
/** Enable/disable fast path optimizations */
fastpaths?: boolean;
/** Custom path format function */
format?: (path: string) => string;
/** Enable capture groups */
capture?: boolean;
/** Match anywhere in string (not anchored) */
contains?: boolean;
/** Match only basename (equivalent to basename) */
basename?: boolean;
/** Match only basename */
matchBase?: boolean;
/** Case insensitive matching */
nocase?: boolean;
/** Enable debug mode */
debug?: boolean;
/** Custom regex flags */
flags?: string;
/** Disable globstars (**) */
noglobstar?: boolean;
/** Disable extglobs (+(a|b)) */
noextglob?: boolean;
/** Disable braces ({a,b}) */
nobrace?: boolean;
/** Disable brackets ([abc]) */
nobracket?: boolean;
/** Custom expand range function for brackets */
expandRange?: (left: string, right: string, options: object) => string;
/** Strict slash handling */
strictSlashes?: boolean;
/** Unescape regex characters */
unescape?: boolean;
/** Maximum regex length */
maxLength?: number;
/** POSIX character classes */
posix?: boolean;
/** Dot handling in patterns */
dot?: boolean;
/** Custom star replacement */
star?: string;
/** Bash compatibility mode */
bash?: boolean;
}
interface MatchResult {
/** Original glob pattern */
glob: string;
/** Parsed state object */
state: {
input: string;
tokens: Token[];
output: string;
negated: boolean;
fastpaths: boolean;
};
/** Compiled regular expression */
regex: RegExp;
/** Whether POSIX mode is enabled */
posix: boolean;
/** Input string being tested */
input: string;
/** Formatted output string */
output: string;
/** Regex match result */
match: RegExpExecArray | null;
/** Whether the pattern matched */
isMatch: boolean;
}
interface Token {
/** Token type (star, text, globstar, etc.) */
type: string;
/** Token value */
value: string;
/** Compiled output for token */
output?: string;
/** Whether token is escaped */
escaped?: boolean;
/** Whether token is negated */
negated?: boolean;
}Picomatch throws specific errors for invalid inputs and provides error handling options:
/** Exception thrown for invalid patterns */
class TypeError extends Error {
constructor(message: string);
}Common Error Conditions:
TypeError: Expected pattern to be a non-empty string - when pattern is empty, null, or not a stringTypeError: Expected input to be a string - when input to test methods is not a string/$^/ (matches nothing) when debug is falseUsage Examples:
// Pattern validation
try {
const matcher = picomatch(''); // Throws TypeError
} catch (error) {
console.log(error.message); // => 'Expected pattern to be a non-empty string'
}
try {
const matcher = picomatch(null); // Throws TypeError
} catch (error) {
console.log(error.message); // => 'Expected pattern to be a non-empty string'
}
// Input validation
try {
picomatch.test(123, /test/); // Throws TypeError
} catch (error) {
console.log(error.message); // => 'Expected input to be a string'
}
// Regex error handling
const validRegex = picomatch.toRegex('*.js'); // Works fine
const invalidRegex = picomatch.toRegex('[invalid'); // Returns /$^/ (matches nothing)
// With debug mode
try {
const debugRegex = picomatch.toRegex('[invalid', { debug: true }); // Throws
} catch (error) {
console.log('Invalid regex pattern detected');
}