NashTech Blog

Understanding Monorepos: What They Are, Why They Matter, and How to Build One with Turborepo

Table of Contents

Introduction

In modern software development, codebases continue to grow in both size and complexity. Teams often maintain multiple applications, shared libraries, and internal tools that must stay aligned. This is one of the main reasons monorepos have become increasingly popular—they streamline development, improve code sharing, and reduce dependency-related issues.

When I first built three React.js applications for a client, each project relied on the same set of core libraries. Because I wasn’t familiar with monorepos at the time, I created three separate repositories. This turned into a maintenance headache: whenever the client updated the core library, I had to apply the change in all three apps and test each one individually. The process was slow, repetitive, and error-prone. Looking back, a monorepo structure would have eliminated most of that duplicated effort and made the entire workflow far more efficient.

In this blog, you’ll learn:

  • What a monorepo is
  • Benefits compared to a traditional (polyrepo) structure
  • Why you should use one
  • A step-by-step guide to setting up a monorepo using Turborepo, PNPM, Next.js, and Playwright

What Is a Monorepo?

A monorepo (monolithic repository) is a single version-controlled repository that contains multiple projects—such as applications, packages, utilities, shared components, and infrastructure code.

Examples:

  • Google, Meta, Microsoft, and Uber use monorepos internally.
  • Many modern frontend ecosystems (like Vercel) recommend monorepos for multi-app structures.

Monorepos can contain:

  • Multiple frontend apps (Next.js, React)
  • Backend services (Node.js, .NET, Go)
  • Shared UI libraries
  • Shared utilities
  • Documentation
  • Configuration files (ESLint, Typescript, Prettier)

All projects live together in one place, managed by a unified toolchain.


Monorepo vs Polyrepo (Normal Repository)

Polyrepo (Traditional)

Each project lives in its own repository.

Pros:

  • Simpler for small projects
  • Clear boundaries
  • Independent versioning

Cons:

  • Harder to share code
  • Duplicate configurations in each repo
  • Dependency management becomes inconsistent
  • Harder to ensure unified coding standards
  • Many repo contexts → switching costs

Monorepo

All related projects in a single repository.

Pros:

  • Easy code sharing (UI components, utils)
  • Single place for dependencies → no version drift
  • Unified tooling (ESLint, TSConfig, Prettier)
  • Atomic commits across multiple packages
  • Simplified collaboration
  • Better CI performance with incremental builds (Turborepo)

Cons:

  • Requires tooling to manage effectively
  • Without good structure, can get messy

Why Use a Monorepo?

You want a monorepo if:

  • Your project has multiple apps that share common code
  • Teams work across multiple services and UI libraries
  • You want consistent tooling and faster development
  • You want powerful caching, shared dependencies, and improved CI/CD

Especially with frameworks like Next.js, monorepos make code sharing extremely smooth.

What Is Turborepo?

Turborepo is a high-performance build system for JavaScript/TypeScript monorepos.
It helps you run tasks (build, lint, test, type-check…) faster and smarter, especially when you have many apps and shared packages.

Remote & Local Caching (the magic part)

Caching is Turborepo’s biggest strength.

Whenever you run a task (e.g., build, test):

  • Turborepo saves the output

  • And most importantly, the inputs (source code, config, env, lockfile)

The next time you run the same task with unchanged inputs, it skips the entire execution and returns the cached result instantly.

✔ Example

Suppose you have:

 
apps/ app1 app2 app3 packages/ ui utils

If you build all three apps:

 
turbo build

Then only change code inside app1 and run again:

 
turbo build

Turborepo:

  • Rebuilds only app1

  • Returns cached results for app2 and app3

  • Skips tests for apps whose code didn’t change

  • Skips builds for shared packages that were unchanged

This can turn a 3-minute build into a 10-second operation.


How to Build a Monorepo Using Turborepo, PNPM, Next.js & Playwright

1. Install PNPM

PNPM is fast, disk-efficient, and works great for monorepos.

npm install -g pnpm

2. Create a Turborepo

pnpm create turbo@latest my-monorepo
cd my-monorepo

Turborepo will generate a structure:

my-monorepo
  ├─ apps/
  ├─ packages/
  ├─ turbo.json
  ├─ package.json

3. Add a Next.js Application

Inside apps/:

cd apps
pnpm create next-app@latest web

Install dependencies at the root (workspace):

pnpm install

Add this to the root package.json:

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ]
}

4. Create a Shared UI Package

Inside packages/:

mkdir ui
cd ui
pnpm init -y

Add React dependency:

pnpm add react react-dom -w

Example component:

// packages/ui/Button.tsx
export const Button = () => <button>Shared Button</button>

Use in Next.js app:

import { Button } from "ui/Button";

5. Configure Turborepo Pipelines

In turbo.json:

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "dev": {
      "cache": false
    }
  }
}

6. Add Playwright to the Monorepo

Install Playwright

pnpm dlx playwright@latest install

Set up Playwright in apps/web:

cd apps/web
pnpm exec playwright init

Using Playwright in a Monorepo

You can:

  • Run E2E tests per application
  • Share test utilities in packages/test-utils

Add script in root package.json:

"scripts": {
  "test:e2e": "turbo run test:e2e"
}

7. Running Everything

Start Dev Mode

pnpm dev

Turborepo runs dev servers for all apps.

Run Build

pnpm build

Utilizes Turborepo caching for faster builds.

Run Playwright

pnpm test:e2e

Conclusion

A monorepo is a powerful way to structure modern applications—especially when you need to share code across multiple apps and packages. By combining Turborepo, PNPM, Next.js, and Playwright, you get:

  • Unified development workflows
  • Faster builds with caching
  • Shared UI libraries and utilities
  • Scalable testing setup

Whether you’re building an e-commerce platform, an enterprise dashboard suite, or internal tools, a monorepo can significantly streamline development and collaboration.

If you’re starting a new large-scale project today, a monorepo is absolutely worth considering.

Picture of Dung Do Minh

Dung Do Minh

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top