Repo
Docs
Core Concepts
Filtering Workspaces

Filtering Workspaces

A monorepo can contain hundreds, or thousands, of workspaces. By default, running turbo run test from the root of the repository will execute the test task in all available workspaces.

Without using a filter, test will be run across all packages

Turborepo supports a --filter flag that lets you select the workspaces you'd like to execute your task in.

With a filter on shared, only the shared package runs test

You can use it to:

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 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

Via global turbo

If you are using a globally installed version of turbo, running from within a workspace automatically filters to that workspace's directory. That means running turbo run test --filter={./packages/shared} from the root of the repository is equivalent to running cd packages/shared && turbo run test.

Running with an explicitly named workspace will always work from anywhere in the repository: turbo run test --filter=shared.

Turborepo's Filter API design and docs were/are inspired by pnpm (opens in a new tab)