Turborepo 1.3
Thursday, June 23rd, 2022
With Turborepo 1.3 we are bringing improved caching and flexibility which includes:
- Restricted hash inputs: Specify the files in a package folder that impact caching with
inputs
. - Root script running and caching: Run and cache
package.json
scripts from the root of the monorepo. - New CI/CD Recipes: We added recipes for using Turborepo with popular CI providers.
Update today by running npm install turbo@latest
.
Pipeline inputs
In addition to environment variables, dependencies, and pipeline configurations, turbo
will consider all non-gitignored files in package folder when calculating each package.json
script's hash fingerprint (the key that turbo
uses to index its cache and to determine if a script needs to be re-executed). With Turborepo 1.3+, you can now specify globs of inputs
in your turbo.json
pipeline
to control which files are relevant for a particular script for caching. This means that you can now express the following in turbo.json
- Ignore changes to all markdown files in a package or app's folder.
- Don't bother rebuilding an app if only its test files have changed.
- Only re-run tests if either source files or test files have been changed in a package or folder.
- and more.
Let's walk through a concrete example: imagine we have a monorepo with a Next.js application for a documentation website in ./apps/docs-site
, some packages, and some markdown files in the root of the monorepo in a ./docs
folder.
.
├── docs/
│ ├── api-reference.md
│ ├── getting-started.md
│ └── intro.md
├── apps/
│ ├── docs-site/
│ │ ├── components/
│ │ ├── pages/
│ │ │ └── [slug].js
│ │ ├── README.md
│ │ └── package.json
│ └── web-site/
│ ├── pages/
│ ├── README.md
│ └── package.json
├── packages/
│ ├── configs/
│ └── ui/
├── package.json
└── turbo.json
Let's assume that the Next.js docs-site
renders the markdown files from the ./docs
folder. We can now set up the build
script in the app's package.json
to use inputs
in turbo.json
to better specify exactly which files are relevant (and which should impact caching) as follows:
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
// ... omitted for brevity
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"docs#build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"],
// Define set of relevant globs which impact caching of docs site
// builds
"inputs": [
"../../docs/**/*.md",
"pages/**",
"components/**",
"package.json"
]
}
}
}
Note: Like outputs
, inputs
are defined relative to the related package.json
, but they can be outside of a given folder (e.g. ../../docs/**
).
Run and cache scripts from the root of your monorepo
As of 1.3, turbo
can now run and cache scripts from the package.json
file at the root of the monorepo, which will help significantly when migrating to Turborepo.
To set this up, specify a root script in your pipeline
configuration in your turbo.json
using the form "//#<script>": {...}
. The //
tells turbo
that the script is relative to the root of the monorepo and not each workspace package.
There are 2 important things to note about root scripts and execution scope:
- If you already have
"build": {...}
in yourpipeline
, but want to include thebuild
script defined in the monorepo's rootpackage.json
file when runningturbo run build
, you may opt the root into the execution's scope by also including"//#build": {...}
in your configuration as well. - Conversely, you do not need to define a generic
"my-script": {...}
entry if all you need is"//#my-script": {...}
.
A sample pipeline that defines the root script check-examples
and opts the root into test
might look like:
{
"name": "my-turborepo",
"private": true,
"scripts": {
"test": "echo 'test!'",
"check-examples": "./check-examples.sh"
},
"devDependencies": {
"turbo": "latest"
}
}
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"]
},
"test": {
"dependsOn": ["^build"],
"outputs": []
},
// This will cause the "test" script from all workspace package.json's
// AND the root package.json to be included when "turbo run test" is run
"//#test": {
"dependsOn": [],
"outputs": []
},
// This will cause the "check-examples" script in the root package.json
// to be run when "turbo run check-examples" is run. Since a general
// "check-examples" script is not defined in the pipeline, only the root
// package.json's "check-examples" script will be included
// when "turbo run check-examples" is run
"//#check-examples": {
"dependsOn": [],
"outputs": [],
"inputs": [
"examples/**/*.ts",
"examples/**/*.tsx",
"examples/**/*.json",
"examples/**/*.js",
"examples/**/*.yaml",
"cli/**/*.ts",
"./scripts/run-example.sh"
]
}
}
}
Note: We suggest specifying inputs
whenever declaring a root task in your pipeline
to improve caching.
New CI/CD Recipes
We added recipes for using Turborepo and Remote Caching with:
If there are other recipes you would like to see here please let us know by opening up a GitHub Discussion (opens in a new tab).
Other Bug Fixes and Improvements
- Improved git operations and hashing
- Better cycle detection in dependency graph analysis
- Added support for Windows ARM 64-bit architectures
- Improved Remote Cache error logging
- Added Storybook to the Design System example
Community
Since releasing Turborepo v1.2 in early April, we've seen incredible adoption and community growth:
- 8.1k+ GitHub Stars (opens in a new tab)
- 275k+ weekly NPM downloads (up ~2x)
- 1,200+ members of the Turborepo Community Discord (opens in a new tab)
- 5.8 years of compute time saved through Remote Caching on Vercel (up ~5x), saving +7 months per week now
Turborepo is the result of the combined work of over 136 contributors including our core team.
This release was brought to you by the contributions of: @gsoltis, @nathanhammond, @tknickman, @jaredpalmer, @zvictor, @ObliviousHarmony, @O4epegb, @rafaeltab, @mcmontseny, @bertspaan, @Jastor11, and @enBonnet
Thank you for your continued support, feedback, and collaboration with us to make Turborepo your build tool of choice.