Thank you for your interest in contributing to Turborepo!
- General dependencies
- Optional dependencies
- Structure of the repository
- Building Turborepo
- Running tests
- Manually testing
turbo
- Debugging tips
- Publishing
turbo
to the npm registry - Contributing to examples
You will need to have these dependences installed on your machine to work on this repository:
- Rust (Repository toolchain)
- NodeJS v20
- pnpm v8
- capnp
- For running tests locally,
jq
andzstd
are also required.- macOS:
brew install jq zstd
- Linux:
sudo apt update && sudo apt install jq zstd
- Windows:
choco install jq zstandard
- macOS:
- On Linux, ensure LLD (LLVM Linker) is installed, as it's not installed by default on many Linux distributions (e.g.
apt install lld
).
In general, there are two major areas in the repository:
- The
crates
directory with the Rust code for theturbo
binary - The
packages
directory with JavaScript packages - the
examples
directory with examples of how to use Turborepo with other tools and frameworks - The
docs
directory with the documentation for Turborepo
- Run
pnpm install
at the root of the repository - Run
cargo build
Turborepo uses reqwest
to make requests to the Remote Cache.
reqwest
supports two TLS
implementations: rustls
and native-tls
. rustls
is a pure Rust implementation of TLS, while native-tls
is a wrapper around OpenSSL. You may select which implementation you want with the native-tls
and rustls-tls
features.
By default, the rustls-tls
feature is selected so that cargo build
works
out of the box. If you wish to select native-tls
, you may do so by running cargo build --no-default-features --features native-tls
.
Important
You will need to have jq
and zstd
installed on your system in order to run tests. See General dependencies for instructions on how to install these tools.
First, install Turborepo globally with your package manager of choice. For instance, with npm, npm install -g turbo
. This will install the turbo
binary in your system's PATH
, making it globally available.
Now, from the root directory, you can run:
- Unit tests
cargo test
- A module's unit tests
cargo test -p <module>
-
Integration tests
pnpm test -- --filter=turborepo-tests-integration
-
A single integration test e.g to run everything in
turborepo-tests/integration/tests/run-summary
:# Build `turbo` first because the next command doesn't run through `turbo` pnpm -- turbo run build --filter=cli pnpm test -F turborepo-tests-integration -- "run-summary"
-
Updating integration tests
turbo run build --filter=cli pnpm --filter turborepo-tests-integration test:interactive
You can pass a test name to run a single test, or a directory to run all tests in that directory.
pnpm --filter turborepo-tests-integration test:interactive tests/turbo-help.t
After building turbo
, you can manually test turbo
for the behaviors you're affecting with your changes. We recommend setting an alias to the built binary so you can call it with your alias.
alias devturbo='~/projects/turbo/target/debug/turbo'
devturbo run build --skip-infer
Important
The --skip-infer
flag is required so that turbo
doesn't try to use a locally installed binary of turbo
. Forgetting to use this flag will cause devturbo
to defer to the binary installed into the repository.
A non-exhaustive list of things to check on:
- Features related to your changes
- Test with and without daemon
- Installation scenarios
- Global only.
turbo
is installed as global binary without a localturbo
in repository. - Local only.
turbo
is installed as local binary without globalturbo
in PATH. turbo` is invoked via a root package script. - Global and local.
turbo
is installed as global binary, and localturbo
in repository. Globalturbo
delegates to localturbo
- Global only.
There are many open-source Turborepos out in the community that you can test with. A few are listed below:
- Next.js
- tldraw
- Tailwind CSS
- Vercel CLI
- This repository! Keep in mind that you'll be building and running
turbo
in the same repository, which can be confusing at times.
Verbose logging can be enabled by using the -v
, -vv
, or -vvv
flag on your turbo
command, depending on the level of logging you're looking for.
turbo build --vvv
In the event of a crash, Rust's crash logs will be written to your temp directory. When turbo
crashes, the location of the crash log will be printed to the console.
The architecture of the Terminal UI makes for a tricky debugging experience. Because the UI writes to the console through stdout
in a specific way, using println!()
statements won't work as expected.
Instead, use eprintln!()
to print to stdout
and output stdout
to a file:
# devturbo is an alias to the debug binary of `turbo` in this case
devturbo run build --ui=tui --skip-infer 2&> ~/tmp/logs.txt
Important
The --skip-infer
flag is required so that turbo
doesn't try to use a locally installed binary of turbo
. Forgetting to use this flag will cause devturbo
to defer to the binary installed into the repository rather than the one you're developing.
See the publishing guide.
Contributing to examples helps the Turborepo community by showcasing how to use Turborepo in real-world scenarios with other tools and frameworks. They can be found in the examples directory of this repository.
The basic
example is the default used by create-turbo
.
For simplicity, each example is treated as a standalone "repository", separate from the rest of the repository, with its own dependencies, lockfile, turbo
version, etc. You are able to run code and make code updates in an example without needing to install the dependencies of the rest of the repository.
Note
You may find that opening your code editor directly in the example's directory that you're working on can give you a better sense of how the example will feel to community members who download the example.
To contribute to an existing example, create your code updates and submit a pull request to the repository. No special steps are required to contribute to an example.
Turborepo works with any framework, tool, or even language. Because of this, the community often expresses interest in creating new examples to showcase Turborepo working with other tooling.
However, we aim to have as few examples in the repository while still showcasing Turborepo's flexibility. By having fewer examples, the core team has a better chance to maintain the collection of examples, keeping them at a higher quality. The ecosystem evolves quickly, and keeping every example up-to-date for every tool requires a wealth of attention. Our goal is to balance the needs of the core team and the community together to keep the Turboverse in a healthy state.
Due to these considerations, we ask that you first open a Discussion before working on a new example for the repository. It's best to make sure ahead of time that the example you'd like to propose will be accepted. Once you have received approval, you can work on and create a pull request for your example.
Each example should have a specific focus when compared to the basic
example. The goal is for an example to show how to use a singular, distinct technology's usage in a Turborepo.
You're encouraged to start with the basic
example and add your specific tool of interest to it. Each example should have as few modifications to the basic
example as possible required to showcase the tool or framework.
Key characteristics of a great example include:
- One technology added to the
basic
example - An updated README at the root of the example directory. Make sure to include any steps required to run the example
- All tasks in
turbo.json
in the example run successfully without any code changes needed - Works with every package manager listed in our Support Policy
Once you've created your example (with prior approval, as discussed above), you can submit a pull request to the repository.
To test out the experience of your example with create-turbo
, run create-turbo
with the --example
flag pointed to a URL to your example's source code:
npx create-turbo@latest --example https://github.com/your-org/your-repo/tree/your-branch/...
This will allow you to use the example as a user would.