Skip to content

Support negation patterns in fs.glob #63959

@TheAlexLichter

Description

@TheAlexLichter

What is the problem this feature will solve?

Node's fs.glob() supports multiple patterns and a separate exclude option, but it does not support conventional negation patterns such as !fixtures/**.

Ecosystem

Negated patterns are supported by commonly used packages such as globby and tinyglobby:

await globby(["src/**/*.js", "!src/generated/**"]);
await glob(["src/**/*.js", "!src/generated/**"]); // tinyglobby

Use cases

Supporting the established syntax would make migration to the built-in API mostly a change of import rather than requiring some kind of translation layer or extra work. It would also allow pattern arrays from existing configuration and CLI options to be reused unchanged.

A common example is selecting tests while excluding fixtures or slower test groups:

const patterns = [
  "test/**/*.test.js",
  "!test/fixtures/**",
  "!test/e2e/**",
];

Other examples include excluding generated files, build output, nested node_modules, etc.

What is the feature you are proposing to solve the problem?

Allow patterns beginning with ! to exclude matching paths:

glob([
  "src/**/*.js",
  "!src/generated/**",
]);

The same behavior would be useful for glob patterns passed to node --test.

The existing exclude option should remain available, especially when exclusion callbacks are needed.

What alternatives have you considered?

Today, applications migrating from either package could inspect and split their pattern arrays:

const patterns = ["src/**/*.js", "!src/generated/**"];

const include = patterns.filter((pattern) => !pattern.startsWith("!"));
const exclude = patterns
  .filter((pattern) => pattern.startsWith("!"))
  .map((pattern) => pattern.slice(1));

glob(include, { exclude });

But this is not a general one-to-one conversion. globby for example considers the order, so a later positive pattern can re-include something excluded by an earlier negative pattern:

await globby([
  "src/**/*.js",
  "!src/generated/**",
  "src/generated/keep.js",
]);

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues that request new features to be added to Node.js.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Awaiting Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions