---
title: query
description: API reference for the `turbo query` command
product: turborepo
type: reference
summary: All flags and options for the `turbo query` command that runs GraphQL queries against your monorepo.
related:
  - /docs/crafting-your-repository/upgrading
  - /docs/reference/system-environment-variables
---

# query



Run GraphQL queries against your monorepo.

```bash title="Terminal"
turbo query [query] [flags]
```

To quickly get the GraphQL schema, use the `--schema`flag.

```bash title="Terminal"
turbo query --schema
```

When no arguments are passed, the command will open a GraphiQL playground to run queries.

```bash title="Terminal"
turbo query
```

When passed a query string, the command will run the query and output the results.

```bash title="Terminal"
turbo query "query { packages { items { name } } }"
```

When passed a file path, the command will read the file and run the query.

```bash title="Terminal"
turbo query query.gql
```

## Shorthands

Shorthands generate GraphQL queries for common operations so you don't need to write them by hand. The JSON output is identical to what you'd get from a raw query.

### `ls`

List packages in your monorepo. This is a shorthand for a `packages` query, equivalent to `turbo ls`.

```bash title="Terminal"
turbo query ls [packages] [flags]
```

With no arguments, lists all packages:

```bash title="Terminal"
turbo query ls
```

```json title="Output"
{
  "packageManager": "npm",
  "packages": {
    "count": 3,
    "items": [
      { "name": "docs", "path": "apps/docs" },
      { "name": "ui", "path": "packages/ui" },
      { "name": "web", "path": "apps/web" }
    ]
  }
}
```

When passed package names, returns detailed information including tasks, dependencies, and dependents:

```bash title="Terminal"
turbo query ls web
```

#### `--filter` (`-F`)

Use pnpm-style package selectors to narrow the package list. Same syntax as [`turbo run --filter`](/docs/reference/run#--filter-string).

```bash title="Terminal"
turbo query ls --filter=web...
turbo query ls -F my-app...
```

#### `--affected`

Show only packages affected by changes between the current branch and `main`.

When combined with `--filter`, returns the intersection: only packages that are both affected **and** match the filter.

```bash title="Terminal"
turbo query ls --affected
turbo query ls --affected --filter=web
```

#### `--output`

Control the output format. Defaults to `pretty` (human-readable).

```bash title="Terminal"
turbo query ls --output json
turbo query ls --output pretty
```

### `affected`

Check which packages or tasks are affected by changes between two git refs.

```bash title="Terminal"
turbo query affected [flags]
```

<Callout type="warn">
  The comparison requires everything between base and head to exist in the
  checkout. If the checkout is too shallow, then all packages will be considered
  changed.

  For example, setting up Git to check out with `--filter=blob:none --depth=0` will ensure `turbo query affected` has the right history to work correctly.
</Callout>

With no flags, returns all affected tasks:

```bash title="Terminal"
turbo query affected
```

```json title="Output"
{
  "data": {
    "affectedTasks": {
      "items": [
        {
          "name": "build",
          "fullName": "web#build",
          "package": { "name": "web" },
          "reason": { "__typename": "TaskFileChanged" }
        }
      ],
      "length": 1
    }
  }
}
```

Task-level detection is more precise than package-level. A task is only reported as affected if its configured [`inputs`](/docs/reference/configuration#inputs) match a changed file, or if an upstream task dependency is affected.

#### `--tasks`

Filter to specific task names. With no values, returns all affected tasks (same as bare `turbo query affected`).

```bash title="Terminal"
turbo query affected --tasks
turbo query affected --tasks build
turbo query affected --tasks build test
```

#### `--packages`

Without `--tasks`, returns affected packages instead of tasks. With no values, returns all affected packages. With values, filters to the named packages.

When combined with `--tasks`, both filters apply (intersection) — only tasks matching the task name **and** belonging to the named packages are returned. This lets you check whether a specific task in a specific package changed:

```bash title="Terminal"
turbo query affected --tasks build --packages web
```

```bash title="Terminal"
turbo query affected --packages
turbo query affected --packages web
turbo query affected --packages web docs
```

```json title="Output"
{
  "data": {
    "affectedPackages": {
      "items": [
        {
          "name": "web",
          "path": "apps/web",
          "reason": { "__typename": "FileChanged" }
        }
      ],
      "length": 1
    }
  }
}
```

#### Understanding affected-package reasons

The `reason` object explains why a package is included. Its `__typename` is
diagnostic output, not a `turbo.json` configuration value.

Most results are package-specific: a source file or a package's resolved
dependencies changed. Some changes must be handled repository-wide because
they change a shared input or Turborepo cannot safely determine a narrower
scope. A repository-wide reason includes every package in the result.

This is related to, but distinct from, cache behavior. For example,
`RootInternalDepChanged` means that a workspace package used by the root
package changed. It selects every package when comparing Git revisions and
also changes the global hash, so every cacheable task misses cache. For the
complete cache model, see [Caching](/docs/crafting-your-repository/caching#root-workspace-dependencies).

Use the reason to diagnose why a package was selected:

```bash title="Terminal"
turbo query affected --packages --base main --head HEAD
```

##### Change-detection reason types

| `reason.__typename`               | Meaning                                                                                                                                  |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `FileChanged`                     | A file in this package changed.                                                                                                          |
| `LockfileChanged`                 | The lockfile comparison found added or removed external dependencies for this package.                                                   |
| `ConservativeRootLockfileChanged` | The root package is included after a lockfile change because it may depend on a workspace package.                                       |
| `RootInternalDepChanged`          | A direct or transitive internal workspace dependency of the root package changed. All packages are selected and the global hash changes. |
| `GlobalDepsChanged`               | A file configured in `globalDependencies` changed. All packages are selected.                                                            |
| `DefaultGlobalFileChanged`        | `turbo.json` or `turbo.jsonc` changed. All packages are selected.                                                                        |
| `LockfileChangeDetectionFailed`   | Turborepo could not safely compare the lockfile versions, so all packages are selected.                                                  |
| `LockfileChangedWithoutDetails`   | The lockfile changed but its previous content was unavailable, so all packages are selected.                                             |
| `GitRefNotFound`                  | The requested Git range could not be resolved, so all packages are selected.                                                             |
| `ScmError`                        | Source-control change detection failed, so all packages are selected.                                                                    |

##### Package-selection reason types

These types describe graph or filter expansion rather than a direct cache
invalidation:

| `reason.__typename`   | Meaning                                                                    |
| --------------------- | -------------------------------------------------------------------------- |
| `DependencyChanged`   | This package was included because one of its dependencies changed.         |
| `DependentChanged`    | This package was included because an included package depends on it.       |
| `InFilteredDirectory` | The package was selected by a directory filter.                            |
| `IncludedByFilter`    | The package was selected explicitly by a filter or package-qualified task. |
| `RootTask`            | A root task was included in the run.                                       |

Run `turbo query --schema` to inspect the exact GraphQL schema supported by
your installed Turborepo version.

#### `--base`

Base git ref for comparison. Defaults to the auto-detected base (e.g. `GITHUB_BASE_REF` on GitHub Actions, or the merge-base with `main`).

Can also be set with the `TURBO_SCM_BASE` environment variable. When both are provided, `--base` takes precedence.

```bash title="Terminal"
turbo query affected --base main
```

#### `--head`

Head git ref for comparison. Defaults to `HEAD`.

Can also be set with the `TURBO_SCM_HEAD` environment variable. When both are provided, `--head` takes precedence.

```bash title="Terminal"
turbo query affected --head my-branch
```

#### `--exit-code`

Exit with code `1` when affected packages or tasks are found, `0` when none are found, or `2` on errors. JSON output is still printed to stdout.

We recommend parsing the JSON output directly for most use cases since it gives you the reason for each change and lets you make more nuanced decisions. `--exit-code` is available as a shorthand for simple cases.

```bash title="Terminal"
turbo query affected --packages my-app --exit-code
```

| Condition                        | Exit code |
| -------------------------------- | --------- |
| Nothing affected                 | `0`       |
| Affected packages or tasks found | `1`       |
| Query error                      | `2`       |

### Migrating from turbo-ignore

`turbo-ignore` is deprecated. `turbo query affected` is its replacement, with more precise task-level change detection that respects your [`inputs`](/docs/reference/configuration#inputs) configuration.

#### Flag mapping

| `turbo-ignore`            | `turbo query affected`                   |
| ------------------------- | ---------------------------------------- |
| `npx turbo-ignore my-app` | `turbo query affected --packages my-app` |
| `--task build`            | `--tasks build`                          |
| `--fallback main`         | `--base main`                            |

#### Key differences

* **More precise detection**: `turbo-ignore` operates at the package level. `turbo query affected` operates at the task input level, so a `.md` change won't trigger a rebuild if your task excludes `*.md` files via `inputs`.
* **Structured output**: The JSON output includes the reason each package or task is affected, which is useful for debugging and automation.

#### CI example

```bash title="Terminal"
affected=$(turbo query affected --packages my-app)
count=$(echo "$affected" | jq '.data.affectedPackages.length')

if [ "$count" -gt 0 ]; then
  echo "my-app is affected, proceeding with build"
else
  echo "my-app is not affected, skipping"
  exit 0
fi
```

## Flags

### `--schema`

Output the GraphQL introspection schema. Cannot be used with a query argument.

```bash title="Terminal"
turbo query --schema
```

### `--variables` (`-V`)

Path to a JSON file containing query variables. Requires a query argument.

```bash title="Terminal"
turbo query query.gql --variables vars.json
```


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)