pwshub.com

Advanced monorepo management with Turborepo 2.0

We all start our first steps in software engineering with small projects. Over time, our projects become larger and more complex. This is where the new architecture of the monorepo project comes into play. There are many tools for developing monorepo projects but in this guide, we will focus on Turborepo and its recent v2 release.

New features in Turborepo 2.0

Advanced Monorepo Management With Turborepo 2.0

Turborepo, developed by Vercel, is a popular tool for creating monorepos in the JavaScript/Typescript ecosystem. It is powerful, fast, and easy to use, whether you want to install it or add it to an existing project.

If you are new to Turborepo and want a deeper dive, check out LogRocket’s guide to building a full-stack TypeScript application with Turborepo.

Recently, the Turborepo team introduced new core features in version 2.0. These features include:

  • A new terminal UI that enhances productivity and development speed with interactive tasks and clearer logs
  • Watch Mode, a dependency-aware task observer for any tool in your monorepo project
  • All-new documentation that offers comprehensive information about monorepository concepts, API references, and tool guides

New terminal UI

In previous versions of Turborepo, when we were working on both libraries and apps simultaneously, we had to read a large amount of log information in one place. Now, starting with version 2.0, we can select specific tasks — whether for a library or an app — and explore their logs individually. This makes it easier to focus and read.

Additionally, in previous versions of Turborepo, we could not interact with the script to execute commands, although many other monorepo tools allowed this. Now we can do this by typing to our scripts via stdin, and entering data directly into the interface. This allows us to run specific test suites using Jest, perform database migrations, and much more.

To make the task interactive, we can update the turbo.json file by adding "persistent": true for the specific task:

{
  "tasks": {
    "dev": {      
      "cache": false,      
      "persistent": true // add and make the task interactive
    }  
  }
}

Then we can select the task in the terminal UI and press Enter to enter the task shell and CTRL+Z to exit.

Watch Mode

Turborepo can run many tasks at the same time, which helps us work faster. However, starting with version 2.0, we can get the most out of Turborepo’s parallelization by using the “watcher” feature that allows us to re-run our code whenever we change something in our source code. Many tools don’t do this or don’t support monorepos, which leads to problems with scripts that depend on other scripts in our repository.

Let’s demonstrate how we can use it easily:

turbo watch dev lint test

Now Turborepo will re-run tasks whenever we make changes to our code using the configuration from turbo.json.

All-new documentation

The Turborepo team has released updated documentation based on the strengths of previous versions and user feedback. They now offer:

  • Monorepo fundamentals and how-tos
  • Guides for integrating any tools with Turborepo
  • Architecture details and improved search

A dive into caching in Turborepo

One of the main reasons Turborepo stands out as a monorepo tool is its use of caching. Turborepo uses caching to speed up the development process and prevent doing the same work repeatedly. Turborepo caching saves a lot of time when working locally, and when combined with remote caching, it becomes even more powerful by sharing the cache across the entire team.

We can try to get our first cache by creating a Turborepo project with the following command:

npx create-turbo@latest // npm
pnpm dlx create-turbo@latest // pnpm

Now, let’s run the build script in package.json, which triggers a turbo build:

 npm run build

This will result in a cache miss because we have never run the previous build script before with this input set in this repository:

Cache Miss Result

If we run turbo build again, we get the following result:

Successful Cache Result

Remote caching with Turborepo

Turborepo stores the results of tasks in the .turbo/cache directory and can share the cache with our teammates and CI to speed up work.

To use it, we need to authenticate with our remote cache provider using the following command:

npx turbo login // npm

Then, link the repository on our machine:

npx turbo link // npm

Now, when we run a task, Turborepo will automatically send the task’s output to the remote cache. The next time the same task is run on any machine authentication with the remote cache, it will retrieve the cached result on the first run.

Creating a monorepo project with Turborepo 2.0

Now, to get a good understanding of the new features in Turborepo 2.0, let’s create our first monorepo project using a basic starter example.

I will first create a monorepo project using Turborepo:

npx create-turbo@latest // npm
pnpm dlx create-turbo@latest // pnpm

This will prompt us for our project name and to select the package manager we want to use:

Creating New Turborepo Project

And voilà, we have just created our monorepo project using Turborepo! Our project includes the following packages/apps:

  • docs: A documentation Next.js app example
  • web: A web Next.js app example
  • @repo/ui: React component library for web and docs apps
  • @repo/eslint-config: Common eslint configurations for libraries and apps
  • @repo/typescript-config: tsconfig.json for libraries and apps

Turborepo Project Structure

Our turbo.json file is set up as follows:

{
  "$schema": "https://turbo.build/schema.json",
  "ui": "tui",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["$TURBO_DEFAULT$", ".env*"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {
      "dependsOn": ["^lint"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Above, we set a specific URL schema for our Turbo configuration. We also defined ui as tui to format the terminal UI. Then, we specified the build, lint, and dev tasks.

Next, we will run all apps with the following command:

pnpm run dev

It runs dev scripts in all app package.json files and opens them in a new terminal with tasks:

Turborepo Terminal Tasks

As we see above, we have two tasks on the left side of the terminal, and task details on the main content of the terminal window. If we navigate to the local URL, we will see more output logs, details about web app states, requests, and more. By switching between tasks, we can examine each detail separately by task content. This is an incredibly useful feature and makes it easier to understand while we are working on a specific app or package.

Lastly, we are going to test the new Watch Mode feature in our Turborepo project. Let’s run all of our tasks with the following command:

turbo watch dev lint

Now, we can see all the tasks on the left sidebar. If we navigate to web#lint task, we can see lint run once:

Running Turborepo Watch Mode

If we change anything in the source code of the web app, the lint task will be re-run like turbo run:

Re-Running Watch Mode

This is a very useful feature to speed up our work.

There are many tools available for working with monorepos, such as Lerna, Nx, and Bazel, each with its own strengths and weaknesses. Some are designed specifically for the frontend, backend, or both, while others excel in large projects or focus mainly on TypeScript.

But Turborepo stands out for its emphasis on speed, caching and parallelization, ease of use, and its efficiency when working with both small and large projects. It also has a large community of users. There are many reasons why you should use Turborepo, especially given the Turborepo 2.0 release.

Thanks for reading. I hope you found this piece useful. Happy coding!


More great articles from LogRocket:

  • Don't miss a moment with The Replay, a curated newsletter from LogRocket
  • Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
  • Use React's useEffect to optimize your application's performance
  • Switch between multiple versions of Node
  • Discover how to use the React children prop with TypeScript
  • Explore creating a custom mouse cursor with CSS
  • Advisory boards aren’t just for executives. Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Hey there, want to help make our blog better?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now

Source: blog.logrocket.com

Related stories
1 day ago - Micro-frontends let you split a large web application into smaller, manageable pieces. It’s an approach inspired by the microservice architecture […] The post How to build scalable micro-frontends with Vike and Vite appeared first on...
1 month ago - ESLint is well adopted and covers virtually all relevant development use cases with its rich feature set. Learn more in this guide. The post ESLint adoption guide: Overview, examples, and alternatives appeared first on LogRocket Blog.
1 month ago - Understanding how to enhance the capabilities of AI and machine learning systems is a valuable skill. One method is Retrieval-Augmented Generation (RAG), a powerful technique that combines retrieval-based methods with generative models to...
2 weeks ago - Large Language Models (LLMs) can be super helpful for for advanced data analysis. We just published a new course on the freeCodeCamp.org YouTube channel that will teach you all about multimodal data analysis using LLMs and Python. This...
2 weeks ago - In the second part of this series, Joas Pambou aims to build a more advanced version of the previous application that performs conversational analyses on images or videos, much like a chatbot assistant. This means you can ask and learn...
Other stories
1 hour ago - Four Prometheus metric types that all developers and DevOps pros should know form the building blocks of an effective observability strategy
2 hours ago - The 2024 Gartner Magic Quadrant positions AWS as a Leader, reflecting our commitment to diverse virtual desktop solutions and operational excellence - driving innovation for remote and hybrid workforces.
3 hours ago - Understanding design patterns are important for efficient software development. They offer proven solutions to common coding challenges, promote code reusability, and enhance maintainability. By mastering these patterns, developers can...
3 hours ago - APIs (Application Programming Interfaces) play an important role in enabling communication between different software systems. However, with great power comes great responsibility, and securing these APIs is necessary to protect sensitive...
3 hours ago - This article aims to celebrate the power of introversion in UX research and design. Victor Yocco debunks common misconceptions, explores the unique strengths introverted researchers and designers bring to the table, and offers practical...