Running tasks
Turborepo optimizes the developer workflows in your repository by automatically parallelizing and caching tasks. Once a task is registered in turbo.json
, you have a powerful new toolset for running the scripts in your repository:
- Use
scripts
inpackage.json
for tasks you need to run often - Use global
turbo
to quickly run custom tasks on-demand - Filter tasks by directories, package names, source control changes, and more
Running tasks through turbo
is powerful because you get one model for executing workflows throughout your repository in development and in your CI pipelines.
Using scripts
in package.json
For tasks that you run frequently, you can write your turbo
commands directly into your root package.json
.
Good to know:
turbo
is an alias for turbo run
- but we recommend using turbo run
in
package.json
and CI workflows to avoid potential collisions with possible
turbo
subcommands that could be added in the future.
These scripts can then be run using your package manager.
You only want to write turbo
commands in your root package.json
. Writing turbo
commands into the package.json
of packages can lead to recursively
calling turbo
.
Using global turbo
Installing turbo
globally lets you run commands directly from your terminal. This improves your local development experience since it makes it easier to run exactly what you need, when you need it.
Additionally, global turbo
is useful in your CI pipelines, giving you maximum control of exactly which tasks to run at each point in your pipeline.
Automatic Package Scoping
When you're in a package's directory, turbo
will automatically scope commands to the Package Graph for that package. This means you can quickly write commands without having to write filters for the package.
In the example above, the turbo build
command will run the build
task for the docs
package using the build
task registered in turbo.json
.
Good to know:
Using a filter will override Automatic Package Scoping.
Customizing behavior
In the documentation for the run
subcommand, you'll find many useful flags to tailor the behavior of turbo run
for what you need. When running global turbo
, you can go faster using workflows like:
- Variations of your most common commands: The
build
script inpackage.json
has the most utility when it isturbo build
- but you might only be interested in a specific package at the moment. You can quickly filter for the specific package you're interested in usingturbo build --filter=@repo/ui
. - One-off commands: Commands like
turbo build --dry
aren't needed often so you likely won't create a script in yourpackage.json
for it. Instead, you can run it directly in your terminal whenever you need it. - Overriding
turbo.json
configuration: Some CLI flags have an equivalent inturbo.json
that you can override. For instance, you may have aturbo build
command configured to use"outputLogs": "full"
inturbo.json
- but you're only interested in seeing errors at the moment. Using globalturbo
, you can useturbo lint --output-logs=errors-only
to only show errors.
Running multiple tasks
turbo
is able to run multiple tasks, parallelizing whenever possible.
This command will run all of the tasks, automatically detecting where it can run a script as early as possible, according to your task definitions.
Ordering of tasks
turbo test lint
will run tasks exactly the same as turbo lint test
.
If you want to ensure that one task blocks the execution of another, express that relationship in your task configurations.
Using filters
While caching ensures you stay fast by never doing the same work twice, you can also filter tasks to run only a subset of the Task Graph.
There are many advanced use cases for filtering in the --filter
API reference but the most common use cases are discussed below.
Filtering by package
Filtering by package is a simple way to only run tasks for the packages you're currently working on.
You can also filter to a specific task for the package directly in your CLI command without needing to use --filter
:
Filtering by directory
Your repository might have a directory structure where related packages are grouped together. In this case, you can capture the glob for that directory to focus turbo
on those packages.
Filtering to include dependents
When you're working on a specific package, you might want to run tasks for the package and its dependents. The ...
microsyntax is useful when you're making changes to a package and want to ensure that the changes don't break any of its dependents.
Filtering by source control changes
Using filters to run tasks based on changes in source control is a great way to run only the tasks for packages that are affected by your changes. Source control filters must be wrapped in []
.
- Comparing to the previous commit:
turbo build --filter=[HEAD^1]
- Comparing to the main branch:
turbo build --filter=[main...my-feature]
- Comparing specific commits using SHAs:
turbo build --filter=[a1b2c3d...e4f5g6h]
- Comparing specific commits using branch names:
turbo build --filter=[your-feature...my-feature]
In general, you can rely on caching to keep your repository fast. When you're using Remote Caching, you can count on hitting cache for unchanged packages.
Combining filters
For even more specificity, you can combine filters to further refine the entrypoints into your Task Graph.
Multiple filters are combined as a union, meaning that the Task Graph will include tasks that match any of the filters. For more information on advanced usage of filters, see the --filter
API reference.
Next steps
When you start running tasks in your repository, you might start noticing that your tasks get faster. Next, you'll explore caching and how turbo
makes it so you never do the same work twice.
Was this helpful?