Filtering Workspaces
A monorepo can contain hundreds, or thousands, of workspaces. By default, running turbo run test
will execute the test
task in all available workspaces.
Turborepo supports a --filter
flag that lets you select the workspaces you'd like to execute your task in.
You can use it to:
- Filter by workspace name
- Filter by workspace directory
- Include dependents and dependencies of matched workspaces
- Execute tasks from the workspace root
- Filter by changes in git history
- Exclude workspaces from selection
Turborepo will run each task against each matched workspace, ensuring that any tasks which depend on it are run first, according to the pipeline
specification in turbo.json
.
Filter Syntax
Multiple filters
You can specify more than one filter by passing multiple --filter
flags to the command:
turbo run build --filter=my-pkg --filter=my-app
Filter by workspace name
When you want to run a script in only one workspace, you can use a single filter: --filter=my-pkg
.
# Build 'my-pkg', letting `turbo` infer task dependencies
# from the pipeline defined in turbo.json
turbo run build --filter=my-pkg
# Build '@acme/bar', letting `turbo` infer task dependencies
# from the pipeline defined in turbo.json
turbo run build --filter=@acme/bar
If you want to run tasks inside several workspaces with similar names, you can use glob syntax: --filter=*my-pkg*
.
# Build all workspaces that start with 'admin-', letting turbo infer task
# dependencies from the pipeline defined in turbo.json
turbo run build --filter=admin-*
Scopes
Some monorepos prepend their workspace names with a scope, such as @acme/ui
and @acme/app
. As long as the scope (@acme
) is unique across the codebase, you may omit it from filters.
- turbo run build --filter=@acme/ui
+ turbo run build --filter=ui
Include dependents of matched workspaces
Sometimes, you'll want to ensure that your shared package isn't affecting any downstream dependencies. For that, you can use --filter=...my-lib
.
If my-app
depends on my-lib
, ...my-lib
will select my-app
and my-lib
.
Including a ^
(...^my-lib
) will select all of my-lib
's dependents, but not my-lib
itself.
# Test 'my-lib' and everything that depends on 'my-lib'
turbo run test --filter=...my-lib
# Test everything that depends on 'my-lib', but not 'my-lib' itself
turbo run test --filter=...^my-lib
Include dependencies of matched workspaces
Sometimes, you'll want to make sure that build
is run in all of the dependencies of the lib you're targeting. For that, you can use --filter=my-app...
.
If my-app
depends on my-lib
, my-app...
will select my-app
and my-lib
.
Including a ^
(my-app^...
) will select all of my-app
's dependencies, but not my-app
itself.
# Build 'my-app' and its dependencies
turbo run build --filter=my-app...
# Build 'my-app's dependencies, but not 'my-app' itself
turbo run build --filter=my-app^...
Filter by directory
Useful for when you want to target a specific directory, not a workspace name. It supports:
- Exact matches:
--filter=./apps/docs
- Globs:
--filter=./apps/*
# Build all of the workspaces in the 'apps' directory
turbo run build --filter=./apps/*
Combining with other syntaxes
When combining directory filters with other syntaxes, enclose in {}
. For example:
# Build all of the workspaces in the 'libs' directory,
# and all the workspaces that depends on them
turbo run build --filter=...{./libs/*}
Filter by changed workspaces
You can run tasks on any workspaces which have changed since a certain commit. These need to be wrapped in []
.
For example, --filter=[HEAD^1]
will select all workspaces that have changed in the most recent commit:
# Test everything that changed in the last commit
turbo run test --filter=[HEAD^1]
Check a range of commits
If you need to check a specific range of commits, rather than comparing to HEAD
, you can set both ends of the comparison via [<from commit>...<to commit>]
.
# Test each workspace that changed between 'main' and 'my-feature'
turbo run test --filter=[main...my-feature]
Ignoring changed files
You can use --ignore
to specify changed files to be ignored in the calculation of which workspaces have changed.
Combining with other syntaxes
You can additionally prepend the commit reference with ...
to match the dependencies of other components
against the changed workspaces. For instance, to select foo
if any of foo
's dependencies have changed in the last commit,
you can pass --filter=foo...[HEAD^1]
.
# Build everything that depends on changes in branch 'my-feature'
turbo run build --filter=...[origin/my-feature]
# Build '@foo/bar' if it or any of its dependencies
# changed in the last commit
turbo run build --filter=@foo/bar...[HEAD^1]
You can even combine []
and {}
syntax together:
# Test each workspace in the '@scope' scope that
# is in the 'packages' directory, if it has
# changed in the last commit
turbo run test --filter=@scope/*{./packages/*}[HEAD^1]
The workspace root
The monorepo's root can be selected using the token //
.
# Run the format script from the root "package.json" file:
turbo run format --filter=//
Excluding workspaces
Prepend !
to the filter. Matched workspaces from the entire filter will be excluded from the set of targets.
For example, match everything except @foo/bar
: --filter=!@foo/bar
. Note that you may need to escape !
as appropriate for your shell (e.g. \!
).
# Build everything except '@foo/bar'
turbo run build --filter=!@foo/bar
# Build all of the workspaces in the 'apps' directory, except the 'admin' workspace
turbo run build --filter=./apps/* --filter=!admin
Turborepo's Filter API design and docs were/are inspired by pnpm