Guide to using glob patterns in Ellipsis configuration.
Glob patterns let you include or exclude sets of paths with compact wildcard expressions, similar to regular expressions or .gitignore patterns.
Glob-matching implementations can vary between libraries, so be sure to test your patterns in our environment. Contact us if you have any questions or run into issues.
* matches any string within a path segment, but not across directory boundaries.
It’s a common mistake to use * when you meant to use the globstar ** - see below.
pattern: src/*✅ src/README.md✅ src/index.ts❌ src/utils/index.ts // '*' does not cross directory boundariespattern: src/*.ts✅ src/index.ts❌ src/README.md // does not have a .ts extension❌ src/utils/index.ts // '*' does not cross directory boundariespattern: *✅ README.md❌ src/index.ts // '*' does not cross directory boundaries
** matches any string (including empty) across directory boundaries. Using ** is the most common way to match all files in a directory.
pattern: **// matches all files everywherepattern: src/**✅ src/main.py✅ src/utils/func.py✅ src/utils/foo/bar/baz/func.py❌ test/test_main.py // does not match 'src/' prefixpattern: assets/**/*.png✅ assets/logo.png✅ assets/icons/flag/us.png❌ assets/logo.svg // does not match '.png' extensionpattern: **/src/**/util/**✅ src/util/README.md✅ src/foo/util/bar/README.md✅ foo/src/bar/util/baz/README.md❌ src/README.md❌ util/src/README.md❌ util/util/README.md❌ srcutil/README.md
Expands into multiple literal alternatives before matching.
So, src/**/*.{ts,tsx} expands into two patterns: src/**/*.ts and src/**/*.tsx
pattern: {src,tests}/**/*.py✅ src/main/app.py✅ tests/unit/test_app.py❌ docs/app.py // directory not in `src` or `tests`pattern: src/**/*.{ts,tsx}✅ src/index.ts✅ src/index.tsx✅ src/utils/index.ts✅ src/utils/index.tsx❌ src/README.md // does not match '.ts' or '.tsx' extension❌ test/index.ts // does not match 'src/' prefix
Negation is usually used in conjunction with multiple patterns.Patterns are evaluated in the order they are listed. So, you typically want your first pattern to be the most inclusive, followed by a series of negations.
patterns: src/utils/** !src/utils/deprecated/**✅ src/utils/users/main.py✅ src/utils/analytics/overview.py❌ src/utils/deprecated/main.py // negated❌ test/test_index.py // did not match any patterns
Make sure to include a negation pattern after the relevant include pattern; otherwise, because patterns are evaluated in order, the negation will have no effect.
For example, the list of patterns ["!src/utils/**", "**"] will not exclude anything, and will instead match all files.
These are less commonly used, but useful to know about.
Match exactly one character from a set or range.
pattern: log[0-9].txt✅ log1.txt✅ log7.txt❌ log10.txt // two digits❌ logx.txt // x not in 0‑9
? matches exactly one character (except /).
pattern: ?.md✅ a.md✅ Z.md❌ README.md // more than one character before the dot
Extglobs are parenthesized patterns preceded by a single symbol that changes how many times the sub‑pattern(s) may appear.
Think of them as “mini‑regular‑expressions” you can drop directly inside a glob.
Syntax
Meaning
Handy mnemonic
@(p1|p2)
Exactly one of the alternatives
“At” least one – exactly one
?(p)
Zero or one occurrence of the pattern
The ? you already know means “maybe”
+(p)
One or more occurrences
+ in regex = “one or more”
*(p)
Zero or more occurrences
* in regex = “zero or more”
!(p)
Anything except the alternatives
! = “not”
Inside the parentheses separate alternatives with pipes (|): @(foo|bar|baz).
pattern: src/!(deprecated)/**✅ src/foo/README.md✅ src/bar/README.md❌ src/deprecated/README.md // negated❌ src/README.md // needs to be in a sub-folder of src, not in src directlypattern: src/**/!(*.test|*.spec).js# ⟶ JS files that are NOT test or spec files✅ src/index.js✅ src/app.js✅ src/foo/index.js❌ src/README.md // no .js extension❌ src/math.test.js // negated '.test'❌ src/calc.spec.js // negated '.spec'❌ app.js // not in src folder
Inline negation is generally not recommended because it can be confusing to read. We recommend splitting into multiple patterns to make it clear which are including and which are excluding. For example, src/**/!(*.test|*.spec).js is equivalent to ["src/**/*.js", "!src/**/*.{test,spec}.js"].
Using * with extglobs:
pattern: src/**/+(components|widgets)/**# ⟶ Any path containing at least one 'components' or 'widgets' segment✅ src/components/Button.tsx✅ src/foo/widgets/Card/index.ts❌ src/utils/helpers.ts
Using ? with extglobs:
pattern: lib/**/?(index|min).mjs# ⟶ Either 'index.mjs' or 'min.mjs', but file may be absent✅ lib/index.mjs✅ lib/foo/min.mjs❌ lib/foo/utils.mjs
Using + with extglobs:
pattern: **/backup/*(202[0-3]|old)/**# ⟶ Folders named 'old' **or** any 2020–2023 year, 0 + times deep✅ backup/old/data.sql✅ backup/2021/db.dump✅ company/backup/2023/archive.tgz
It’s common for developers to reach for .gitignore-style patterns, which don’t require using the globstar **. So, we expand patterns that don’t end in /** to include all files in the directory.
It’s a common mistake to include a negation pattern without any matching patterns before it. So, if all patterns in a list are negated, Ellipsis will automatically insert a ** pattern to run first in the list to ensure some files are included.