diff --git a/docs/site/app/(no-sidebar)/blog/[...slug]/page.tsx b/docs/site/app/(no-sidebar)/blog/[...slug]/page.tsx index 929374caba9e9..068fda49ef513 100644 --- a/docs/site/app/(no-sidebar)/blog/[...slug]/page.tsx +++ b/docs/site/app/(no-sidebar)/blog/[...slug]/page.tsx @@ -48,11 +48,11 @@ export default async function Page(props: { const Mdx = page.data.body; return ( -
+
@@ -60,9 +60,6 @@ export default async function Page(props: {
- {/* TODO: Currently, the content is controlling the

to get the heading centered. - /* Needs to be controlled here so we can just write the markdown and it will do the right thing. - * */}

); diff --git a/docs/site/components/authors.tsx b/docs/site/components/authors.tsx index 6339852e56ddb..ecb6297b96570 100644 --- a/docs/site/components/authors.tsx +++ b/docs/site/components/authors.tsx @@ -8,7 +8,7 @@ export function Authors({ authors }: { authors: Author[] }): JSX.Element {
4 && "max-w-3xl" )} > diff --git a/docs/site/components/avatar.tsx b/docs/site/components/avatar.tsx index ce860121ca2fe..08f8dbc411cb2 100644 --- a/docs/site/components/avatar.tsx +++ b/docs/site/components/avatar.tsx @@ -19,7 +19,7 @@ export function Avatar({ width={32} />
-
+
Name
{name}
{xUsername ? ( @@ -27,7 +27,7 @@ export function Avatar({
X
+
{children} - {update !== undefined && (
Last updated {update}
)} diff --git a/docs/site/components/in-version.tsx b/docs/site/components/in-version.tsx index ec9008e7b45e0..6efa34ac30f29 100644 --- a/docs/site/components/in-version.tsx +++ b/docs/site/components/in-version.tsx @@ -5,7 +5,7 @@ import { fetchDistTags } from "../app/api/binaries/version/route"; // This is an optimization to avoid fetching the latest version of turbo from npm // It doesn't strictly need to always be up to date, but it will avoid a network // request on page loads that use this component. -const STATIC_LATEST_RELEASE = "2.4.4"; +const STATIC_LATEST_RELEASE = "2.1.3"; if (!valid(STATIC_LATEST_RELEASE)) { throw new Error(`Invalid static version "${STATIC_LATEST_RELEASE}"`); diff --git a/docs/site/content/blog/turbo-2-5.mdx b/docs/site/content/blog/turbo-2-5.mdx new file mode 100644 index 0000000000000..88c0076033ced --- /dev/null +++ b/docs/site/content/blog/turbo-2-5.mdx @@ -0,0 +1,242 @@ +--- +title: Turborepo 2.5 +date: 2025/3/3 +description: 'Sidecar tasks, `--continue` flexibility, turbo.jsonc, Bun pruning, `$TURBO_ROOT$`, OpenAPI viewer, and more.' +tag: 'web development' +ogImage: /images/blog/turbo-2-5/x-card.png +--- + +import { Authors } from '#/components/authors'; +import { Date } from '#/components/blog/date'; +import { Accordion, Accordions } from '#/components/accordion'; + +# Turborepo 2.5 + +Thursday, March 3rd, 2025 + + + +Turborepo 2.5 includes a number of improvements to enhance your repository: + +- [**Sidecar tasks**](#sidecar-tasks): Use `with` to ensure persistent tasks always run together +- [**Flexibility for `--continue`**](#improved-control-for---continue-behavior): Only continue running tasks when dependencies are successful +- [**`turbo.jsonc`**](#add-comments-to-your-turborepo-configuration-files): Write comments directly in your configuration file +- [**`prune` for Bun**](#pruned-monorepos-for-bun-repositories): You can now use `turbo prune` in Bun repositories +- [**`$TURBO_ROOT$`**](#reference-your-workspace-root-with-the-turbo_root-microsyntax): Reference the Workspace root in `turbo.json` +- [**OpenAPI viewer**](#openapi-specification-viewer-for-self-hosting): Human-readable OpenAPI spec for self-hosted Remote Caches + +Upgrade today by running `npx @turbo/codemod migrate` or get started with `npx create-turbo@latest`. + +## Sidecar tasks + +In some cases, you want to ensure two long-running tasks are always running at the same time. For example, you may have a web application that makes requests to another application in your monorepo. Running the web application by itself may not be useful, since the backend API application won’t be available to serve its requests. + +You may have tried to use `dependsOn` to create this relationship - but quickly discovered that depending on a long-running task isn’t allowed. A long-running task never exits, so the dependent task would never run. This meant you’d have to carefully craft a [`--filter`](/repo/docs/reference/run#--filter-string) to ensure those resources are available—and make sure everyone in the repo knows to use it. + +Instead, we’re introducing the `with` key so you can guarantee that a dependent long-running task always runs _with_ the long-running tasks that it depends on at runtime. + +```json title="apps/web/turbo.json" +{ + "tasks": { + "dev": { + "with": ["api#start"], + "persistent": true, + "cache": false + } + } +} +``` + +Using this [Package Configuration](/repo/docs/reference/package-configurations), anytime that the `web` application’s `dev` task is started, the `api`'s `start` task will also run using [the `package#task` microsyntax](/repo/docs/crafting-your-repository/configuring-tasks#depending-on-a-specific-task-in-a-specific-package). + +[Visit the documentation](/repo/docs/reference/configuration#with) to learn more. + +## Improved control for `--continue` behavior + +By default, Turborepo stops running tasks when it encounters a task that has failed. You can alter this behavior using the `--continue` flag, instructing Turborepo to continue running tasks, even when one or more tasks have failed. + +While the `--continue` flag is useful, there are times when running tasks whose dependencies have failed will only result in more failures. For these situations, we’ve added a new value to the `--continue` flag in this release: `--continue=dependencies-successful`. + +```bash title="Terminal" +turbo run test --continue=dependencies-successful +``` + +When using this value, all dependencies for a task must be successful for the dependent task to run. + +[Learn more in the documentation](/repo/docs/reference/run#--continueoption). + +The Turborepo core team would like to thank @jenseng for contributing this feature. + +## Add comments to your Turborepo configuration files + +You can now use JSONC (`turbo.jsonc`) for your configuration files, allowing you to add useful comments to your configuration. + +```json title="./turbo.jsonc" +{ + "tasks": { + "test": { + // Our tests need their dependencies to be built first + "dependsOn": ["^build"] + } + } +} +``` + +## Pruned monorepos for Bun repositories + +`turbo prune` creates a partial monorepo for a target package, and is especially useful for [creating lightweight Docker images from monorepos](/repo/docs/guides/tools/docker). This command has been available for pnpm, npm, and Yarn repositories in previous versions of Turborepo. + +In this release, `turbo prune` is now available for Bun v1.2+, which has introduced a text-based lockfile that we can now read and analyze. + +```bash title="Terminal" +turbo prune web +``` + +To learn more about `turbo prune`, [visit the documentation](/repo/docs/reference/prune). + +The Turborepo core team would like to thank @camero2734 for contributing this feature. + +## Reference your workspace root with the `$TURBO_ROOT$` microsyntax + +In some situations, you’re forced to break out of package boundaries in a monorepo. This could be due to a number of constraints, like tooling that doesn’t conform to modern package manager workspaces or incremental migration workflows that take you out of ideal conditions. + +In the past, you’d need to write paths in `turbo.json` that traverse to the workspace root, since globs are anchored to the root of packages: + +```json title="./turbo.json" +{ + "tasks": { + "build": { + "inputs": ["../../important-file.txt"] + } + } +} +``` + +While this pattern does work, it can lead to inconsistencies in some cases: + +- Some packages may need `../` while others need `../../` +- A developer could potentially move a package to a different location so that the path isn’t correct + +Instead, you can now use the `$TURBO_ROOT$` microsyntax: + +```json title="./turbo.json" +{ + "tasks": { + "build": { + "inputs": ["$TURBO_ROOT$/important-file.txt"] + } + } +} +``` + +Now, this file glob is guaranteed to always start at the root of your workspace. + +[Visit the documentation](/repo/docs/reference/configuration#turbo_root) to learn more. + +## OpenAPI specification viewer for self-hosting + +Turborepo is proudly open-source with a public specification for its Remote Caching protocol. While [Vercel Remote Cache is a free-to-use managed option](https://vercel.com/docs/monorepos/remote-caching), the OpenAPI spec allows the community to create implementations for Remote Caching of their own. + +We’ve published [the Remote Cache spec as JSON to the web](/api/remote-cache-spec) for some time, and have recently added a human-friendly version of the spec at [https://turbo.build/repo/docs/openapi](https://turbo.build/repo/docs/openapi). + +[Visit the Remote Caching documentation](/repo/docs/core-concepts/remote-caching#remote-cache-api) to learn more. + +## Other changes + + + + + + - feat(boundaries): package rules ([#10160](https://github.com/vercel/turborepo/pull/10160)) + - feat(boundaries): package name as tag punning ([#10151](https://github.com/vercel/turborepo/pull/10151)) + - feat(boundaries): implicit dependencies ([#10117](https://github.com/vercel/turborepo/pull/10117)) + - feat(process): distinguish between signals used to kill children ([#10049](https://github.com/vercel/turborepo/pull/10049)) + - feat(boundaries): auto ignore ([#10147](https://github.com/vercel/turborepo/pull/10147)) + - feat(clone): turbo clone ([#9904](https://github.com/vercel/turborepo/pull/9904)) + - feat(boundaries): support tsconfig path aliases ([#10002](https://github.com/vercel/turborepo/pull/10002)) + - feat(query): add schema flag ([#10052](https://github.com/vercel/turborepo/pull/10052)) + - feat(ls): add package path to ls ([#10079](https://github.com/vercel/turborepo/pull/10079)) + + + + + + - fix(turbo_json): avoid workspace validation errors ([#10211](https://github.com/vercel/turborepo/pull/10211)) + - fix(bun): deserialize correctly and use optionalPeers ([#10219](https://github.com/vercel/turborepo/pull/10219)) + - fix: update env variables supported by nitro ([#10176](https://github.com/vercel/turborepo/pull/10176)) + - fix: mark type of flat config export to satisfy Linter.Config[] ([#10128](https://github.com/vercel/turborepo/pull/10128)) + - fix(eslint): array type lints ([#10139](https://github.com/vercel/turborepo/pull/10139)) + - fix(bun): properly handle bun lockfile keys ([#10137](https://github.com/vercel/turborepo/pull/10137)) + - fix: eslint-config-turbo module export ([#10105](https://github.com/vercel/turborepo/pull/10105)) + - fix: correctly forward passthrough arguments when using pkg#task format ([#10087](https://github.com/vercel/turborepo/pull/10087)) + - fix(boundaries): support import attributes ([#10078](https://github.com/vercel/turborepo/pull/10078)) + - fix(boundaries): unnecessary tsconfig warnings ([#10104](https://github.com/vercel/turborepo/pull/10104)) + - fix(affected): consider turbo.jsonc as a default global dependency ([#10106](https://github.com/vercel/turborepo/pull/10106)) + - fix(prune): support copying turbo.jsonc ([#10107](https://github.com/vercel/turborepo/pull/10107)) + - fix(cli): no longer attempt to parse task name as continue value ([#10097](https://github.com/vercel/turborepo/pull/10097)) + - fix: affected_packages's optimization flow ([#9950](https://github.com/vercel/turborepo/pull/9950)) + - fix(@turbo/repository): revert "chore(deps): update git2 to 0.20.0" ([#10045](https://github.com/vercel/turborepo/pull/10045)) + - fix(process): revert "feat(process): differentiate between child interruption and killing" ([#10046](https://github.com/vercel/turborepo/pull/10046)) + - fix: filter logic ([#9653](https://github.com/vercel/turborepo/pull/9653)) + - fix(packages): no longer match versionless packages ([#10056](https://github.com/vercel/turborepo/pull/10056)) + - fix(engine): no longer error if provided task is omitted by filter ([#10051](https://github.com/vercel/turborepo/pull/10051)) + + + + + + - docs: layout redesign ([#10178](https://github.com/vercel/turborepo/pull/10178)) + - docs: fix text colors in a few spots ([#10213](https://github.com/vercel/turborepo/pull/10213)) + - docs: remove stale callout ([#10217](https://github.com/vercel/turborepo/pull/10217)) + - docs: links for OpenAPI spec for both human-readable and JSON ([#10216](https://github.com/vercel/turborepo/pull/10216)) + - docs: add a snippet to with ([#10215](https://github.com/vercel/turborepo/pull/10215)) + - docs: mention JSONC support ([#10214](https://github.com/vercel/turborepo/pull/10214)) + - docs: fix the incorrect export keyword ([#10235](https://github.com/vercel/turborepo/pull/10235)) + - docs: add checkout optimization for --affected ([#10188](https://github.com/vercel/turborepo/pull/10188)) + - docs: use schema from current @turbo/types ([#10197](https://github.com/vercel/turborepo/pull/10197)) + - docs: switch turbo run to turbo watch for --experimental-write-cache ([#10199](https://github.com/vercel/turborepo/pull/10199)) + - docs(run): fix passthrough arg behavior ([#10167](https://github.com/vercel/turborepo/pull/10167)) + - docs: bump openapi framework version ([#10172](https://github.com/vercel/turborepo/pull/10172)) + - docs: fix typos ([#10182](https://github.com/vercel/turborepo/pull/10182)) + - docs: update fallback OG image ([#10174](https://github.com/vercel/turborepo/pull/10174)) + - docs: enhance examples tables ([#10173](https://github.com/vercel/turborepo/pull/10173)) + - docs: fix typos in documentation files ([#10192](https://github.com/vercel/turborepo/pull/10192)) + - docs: fix typos in documentation files ([#10124](https://github.com/vercel/turborepo/pull/10124)) + - docs: update storybook initiation instructions ([#10145](https://github.com/vercel/turborepo/pull/10145)) + - docs: clarify TURBO_TEAM slug usage ([#10102](https://github.com/vercel/turborepo/pull/10102)) + - fix: adds callout for installation instructions for PNPM ([#10100](https://github.com/vercel/turborepo/pull/10100)) + - docs: add release phases to support policy ([#10091](https://github.com/vercel/turborepo/pull/10091)) + - docs: remove ls from Experimental phase in Support Policy ([#10108](https://github.com/vercel/turborepo/pull/10108)) + - docs: fix code black background colors ([#10141](https://github.com/vercel/turborepo/pull/10141)) + - fix(docs): prefix environment variable for search dialog ([#10142](https://github.com/vercel/turborepo/pull/10142)) + - fix(docs): fix commas in package exports example ([#10143](https://github.com/vercel/turborepo/pull/10143)) + - docs: open source site source code ([#10127](https://github.com/vercel/turborepo/pull/10127)) + - docs: remove experimental warning from ls command ([#10096](https://github.com/vercel/turborepo/pull/10096)) + - docs: add hybrid approach to vitest guide ([#10092](https://github.com/vercel/turborepo/pull/10092)) + - docs: fix typo on continue docs ([#10041](https://github.com/vercel/turborepo/pull/10041)) + - docs: add explicit mention for capturing multiple .env files ([#10061](https://github.com/vercel/turborepo/pull/10061)) + - docs: fix json title for Watch Mode docs ([#10085](https://github.com/vercel/turborepo/pull/10085)) + - docs: upgrades for Vitest doc and add with-vitest example ([#10063](https://github.com/vercel/turborepo/pull/10063)) + - fix(docs): asset importing failure for OG images ([#10159](https://github.com/vercel/turborepo/pull/10159)) + + + + + + - fix: unexpected top-level property default in base.js eslint config ([#10240](https://github.com/vercel/turborepo/pull/10240)) + - fix(example): remove obsolete @types/react-native from with-react-native-web ([#10190](https://github.com/vercel/turborepo/pull/10190)) + - docs: update README.md in examples with-tailwind to correctly reference .ts config files instead of .js ([#10057](https://github.com/vercel/turborepo/pull/10057)) + - docs: fix JSDoc annotation for ESLint flat configs of basic example ([#10089](https://github.com/vercel/turborepo/pull/10089)) + - feat(examples): add example with-solid ([#10144](https://github.com/vercel/turborepo/pull/10144)) + + + + + +## Acknowledgments and community + +Turborepo is the result of the combined work of all of its contributors, including our core team: [Anthony](https://github.com/anthonyshew), [Chris](https://github.com/chris-olszewski), [Dimitri](https://github.com/dimitropoulos), [Nicholas](https://github.com/NicholasLYang), and [Tom](https://github.com/tknickman). + +Thank you for your continued support, feedback, and collaboration to make Turborepo your build tool of choice. To learn how to get involved, [visit the Community page](/repo/docs/community). + +We also thank everyone who contributed to this release of Turborepo: @beaussan, @bohongu, @camero2734, @cprussin, @dinglindong, @jenseng, @jimmycathy, @kevincatty, @mm-webx, @ognevny, @pi0, @pudongair, @rootdiae, @shinjith-dev, @sicarius97, @ssshashank, @Tigatok, @todaymoon, @Tyoneb, @victorlagerfors, @vinayaksodar, @wmjae, @x-N0, and @xiaobei0715. diff --git a/docs/site/content/repo-docs/crafting-your-repository/configuring-tasks.mdx b/docs/site/content/repo-docs/crafting-your-repository/configuring-tasks.mdx index abc553185e106..ee8e34f631c63 100644 --- a/docs/site/content/repo-docs/crafting-your-repository/configuring-tasks.mdx +++ b/docs/site/content/repo-docs/crafting-your-repository/configuring-tasks.mdx @@ -304,6 +304,24 @@ With the Root Task now registered, `turbo run lint:root` will now run the task. In large monorepos with many teams, this allows teams greater control over their own tasks. To learn more, visit [the Package Configurations documentation](/repo/docs/reference/package-configurations) +### Long-running tasks with runtime dependencies + +You might have a long-running task that requires another task to always be running at the same time. For this, use [the `with` key](/repo/docs/reference/configuration#with). + +```json title="./apps/web/turbo.json" +{ + "tasks": { + "dev": { + "with": ["api#dev"], + "persistent": true, + "cache": false + } + } +} +``` + +A long-running task never exits, meaning you can't depend on it. Instead, the `with` keyword will run the `api#dev` task whenever the `web#dev` task runs. + ### Performing side-effects Some tasks should always be run no matter what, like a deployment script after a cached build. For these tasks, add `"cache": false` to your task definition. diff --git a/docs/site/content/repo-docs/reference/configuration.mdx b/docs/site/content/repo-docs/reference/configuration.mdx index ade7b2a85c5c8..0799d55d75989 100644 --- a/docs/site/content/repo-docs/reference/configuration.mdx +++ b/docs/site/content/repo-docs/reference/configuration.mdx @@ -4,6 +4,7 @@ description: Learn how to configure Turborepo through `turbo.json`. --- import { Callout } from '#/components/callout'; +import { InVersion } from '#/components/in-version'; import { ExperimentalBadge } from '#/components/experimental-badge'; import Link from 'next/link'; @@ -518,6 +519,22 @@ Label a `persistent` task as `interruptible` to allow it to be restarted by `tur that are affected. However, if a task is persistent, it will not be restarted by default. To enable restarting persistent tasks, set `interruptible` to `true`. +### `with` + +A list of tasks that will be ran alongside this task. This is most useful for long-running tasks that you want to ensure always run at the same time. + +```json title="./apps/web/turbo.json" +{ + "tasks": { + "dev": { + "with": ["api#dev"], + "persistent": true, + "cache": false + } + } +} +``` + ## Boundaries The `boundaries` tag allows you to define rules for the [`boundaries` command](/repo/docs/reference/boundaries). diff --git a/docs/site/mdx-components.tsx b/docs/site/mdx-components.tsx index 5b1cb6cb4c706..e09874698f7d8 100644 --- a/docs/site/mdx-components.tsx +++ b/docs/site/mdx-components.tsx @@ -5,6 +5,7 @@ import { Heading } from "fumadocs-ui/components/heading"; import type { ReactNode, Ref } from "react"; import { NodeJsLogo } from "./app/_components/logos"; import { ThemeAwareImage } from "./components/theme-aware-image"; +import { cn } from "./components/cn"; const iconAdder = (title?: string): JSX.Element | null => { if (title?.endsWith("turbo.json")) { @@ -45,6 +46,17 @@ const iconAdder = (title?: string): JSX.Element | null => { export const mdxComponents: MDXComponents = { ...defaultComponents, + h1: (props) => { + const { className, ...rest } = props; + + return ( + + ); + }, h2: (props) => ( ), @@ -54,6 +66,9 @@ export const mdxComponents: MDXComponents = { h4: (props) => ( ), + a: (props) => ( +
+ ), pre: ({ ref: _ref, title, diff --git a/docs/site/public/images/blog/turbo-2-5/x-card.png b/docs/site/public/images/blog/turbo-2-5/x-card.png new file mode 100644 index 0000000000000..59555eb036a0f Binary files /dev/null and b/docs/site/public/images/blog/turbo-2-5/x-card.png differ