---
title: Filtering Packages
description: Only build the packages you care about
---

import Callout from "../../../components/Callout";
import HeartIcon from "@heroicons/react/solid/HeartIcon";

# Filtering Packages

Filtering packages allows you to target your tasks to only the packages you care about.
Turborepo supports a `pnpm`-like `--filter` flag that allows you to select the packages
that will act as "entry points" into your monorepo's package/task graph.
You can filter your project by package name, package directory, whether packages include dependents/dependencies, and by changes
in git history.

`turbo` will run each task against each matched package, ensuring that any dependencies
are run first, according to the `pipeline` specification in [`turbo.json`](/docs/reference/configuration#pipeline).

## Filter Syntax

Filters specify combinations of package(s)/apps, directories, and git commits to act as entrypoints
for execution.

Multiple filters can be combined to select distinct sets of targets. Additionally, filters
can also exclude targets. A target that matches any filter and is not explicitly excluded will
be in the final entrypoint selection.

Turborepo's filter syntax is based on pnpm's filter syntax, so it should feel familiar to pnpm users.

### Filter by package

Supports exact matches (`--filter=my-pkg`), and globs (`--filter=*my-pkg*`) are supported.
Scoped packages (`@foo/bar`) can be abbreviated to just the package name (`bar`) as long as the package name
is unique within the monorepo (e.g. `@foo/bar` exists, but `@baz/bar` does not).

The monorepo's root package can be selected using the token `//`.

```sh
# Build 'my-pkg', letting turbo infer task dependencies from the pipeline defined in turbo.json
turbo run build --filter=my-pkg
# Build '@foo/bar', letting turbo infer task dependencies from the pipeline defined in turbo.json
turbo run build --filter=@foo/bar
# Build all packages that start with 'admin-', letting turbo infer task dependencies from the pipeline defined in turbo.json
turbo run build --filter=admin-*
# Run the format script from the root "package.json" file:
turbo run format --filter=//
```

### Include dependents of matched packages

Prepend `...` to the filter. If `my-app` depends on `my-lib`, `...my-lib` will select `my-app` and `my-lib`.
Optionally including a `^` (`...^my-lib`) will select all of `my-lib`'s dependents, but not `my-lib` itself. In this case, just `my-app` will be
selected.

```sh
# 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 packages

Append `...` to the end of the filter. If `my-app` depends on `my-lib`, `my-app...` will select `my-app` and `my-lib`.
Optionally including a `^` (`my-app^...`) will select all of `my-app`'s dependencies, but not `my-app` itself. In this case, just `my-lib` will be selected.

```sh
# 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 or directory tree

Supports exact matches (`--filter=./apps/docs`) and globs (`--filter=./apps/*`).
When combined with other components, must be enclosed in `{}` (`--filter=...{./libs/*}`).

```sh
# Build all of the packages in the 'apps' directory
turbo run build --filter=./apps/*
# Build all of the packages in the 'libs' directory, and all the packages that depends on them
turbo run build --filter=...{./libs/*}
```

### Filter by changed packages

Use the set of files changed since a specified commit to calculate packages. Enclose references in
`[]`. For example, `--filter=[HEAD^1]` will select all packages that have changed in the most recent
commit. 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>]`.

You can use [`--ignore`](/docs/reference/command-line-reference#--ignore) to specify changed files to be ignored in the calculation of which packages have changed.

You can additionally prepend the commit reference with `...` to match the dependencies of other components
against the changed packages. For instance, to select `foo` if any of `foo`'s dependencies have changed in the last commit,
you can pass `--filter=foo...[HEAD^1]`. Note that this feature is different from `pnpm`'s syntax.

```sh
# Test everything that changed in the last commit
turbo run test --filter=[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]
# Test each package 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]
# Test each package that changed between 'main' and 'my-feature'
turbo run test --filter=[main...my-feature]
```

### Excluding packages

Prepend `!` to the filter. Matched packages 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. `\!`).

```sh
# Build everything except '@foo/bar'
turbo run build --filter=!@foo/bar
# Build all of the packages in the 'apps' directory, except the 'admin' package
turbo run build --filter=./apps/* --filter=!admin
```

<Callout type="idea" icon={<HeartIcon className="mt-1 h-5 w-5 text-gray-400" aria-hidden="true" />}>
Turborepo's Filter API design and docs were/are inspired by [pnpm](https://pnpm.io/filtering)
</Callout>
