---
title: File Inputs
description: How to configure Turborepo file inputs
---

import { Callout } from "../../../../../components/Callout";

# File Inputs

By default, a workspace is considered to have been updated when any of the files in that workspace have changed. However, not every file change inside of the entire repo should result in rerunning a task. Turborepo gives you the tools to make sure that you can define every file that matters.

## Global Files

Almost every repository has some configuration that appears at the root of the repository. These files have the potential to impact the behavior of child workspaces.

### `package.json` and `turbo.json`

By default, Turborepo includes the root `package.json` and the root `turbo.json` file into the global hash. You do not need to specify them separately.

### Specifying Additional Inputs

If there are additional files that should be considered for every single workspace, such as a root `tsconfig.json` you should specify that in `globalDependencies`:

```jsonc filename="/turbo.json"
{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": ["tsconfig.json"],
  "pipeline": {
    "type-check": {}
  }
}
```

<Callout type="info">
  This customization is _additive_ to Turborepo's default behavior for `package.json` and `turbo.json`.
</Callout>

In this example every single task in the turborepo would be rerun when the root `tsconfig.json` file changes.

## Workspace Files

In addition to global files, which appear outside of any workspace, you may also specify which files to include on a per-workspace basis.

### `package.json` and `turbo.json`

The contents of each workspaces's `package.json` and `turbo.json` (if it exists) are automatically considered for workspace hashes. This behavior is not configurable.

### Turborepo's Default Behavior

The default behavior of Turborepo is to inspect the repository and identify which files should be included in the hash calculation. Turborepo typically uses Git to identify which files to consider:

- All of the files which appear in the Git index which are children of the workspace directory.
- All of the untracked files which are children of the workspace directory and are not `.gitignore`d.

If Git is not available, or a repository has not been setup, we attempt to approximate the contents which would appear in the Git index using the following strategy:

- Include all of the files which are children of a workspace directory.
- Exclude all of the files which appear in the root `.gitignore` and the workspace directory's `.gitignore`.

<Callout type="info">
  These two approaches do not always produce identical results! The scenarios where this does not produce identical results:

- `.gitignore` files at other places in the directory hierarchy.
- Files added to the Git index which are also specified inside of a `.gitignore`.

You should aim to have both Git and the Git index of your repository available for maximum correctness.

</Callout>

### Customizing the Behavior

<Callout>
  Customizing the `inputs` immediately opts out of the default behavior. You must manually specify via `pipeline.<task>.inputs` all of the files that should be considered.

For convienence, you can use the special string `$TURBO_DEFAULT$` within an inputs array to automatically include all files considered in the default behavior. This allows
you to customize the inputs without needing to manually specify all of the files that would have been considered by default.

</Callout>

For some tasks it is worthwhile to reduce the number of file inputs into the task hash consideration. Very few tasks depend on the contents of `README.md`. Specifying just the files that matter can increase the frequency of cache hits.

For example, in many `build` tasks the only files that may matter might appear in the `src` directory. Alternatively, a `test` task may depend only on files in the `src` and `test` directory. You can specify this using glob patterns passed to `pipeline.<task>.inputs`:

```jsonc filename="/turbo.json"
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "inputs": ["src/**"]
    },
    "test": {
      "inputs": ["src/**", "test/**"]
    }
  }
}
```

These glob patterns are relative to the workspace's path, so, for `build` inside of the `website` app, it would treat `/apps/website/src/**` as file inputs, and, for `build` inside of the `utils` workspace it would consider `/packages/utils/src/**` as file inputs.

If a task depends on another task which specifies file dependencies they do not need to be listed again. Dependency relationships between tasks can be used to ensure that all file dependencies are met:

```jsonc filename="/turbo.json"
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["src/**"]
    },
    "test": {
      // This task dependsOn build...
      "dependsOn": ["build"],
      // ...which means that it does not need to specify "src/**" here:
      "inputs": ["test/**"]
    }
  }
}
```

This pattern can be used to save yourself from needing to repetitively enumerate a list of file globs for every single task.

You may also want to keep the default behavior, but only include, or exclude a few files. You can use the special string `$TURBO_DEFAULT$` to include all of the files that would have been considered by default:

```jsonc filename="/turbo.json"
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "inputs": ["$TURBO_DEFAULT$", "!README.md", "a-git-ignored-file.txt"]
    }
  }
}
```
