Mastering Monorepos: Set Up with Turborepo
Ezeikel Pemberton
March 30, 2026

Photo: Pexels
Hey there, fellow developer! If you're reading this, chances are you're intrigued by the concept of monorepos and want to know how to set up a robust, production-ready environment using Turborepo. You've come to the right place. In this post, I'll guide you through the process, sharing practical insights and actionable advice to make your monorepo journey as smooth as possible.
Why Monorepos?
Before diving into the setup, let's quickly touch on why you might want to use a monorepo in the first place. Monorepos can be a game-changer for teams of any size. They allow you to:
- Centralize code: Manage multiple projects within a single repository.
- Share code easily: Reuse libraries and utilities across projects without duplication.
- Simplify dependencies: Handle all dependencies in one place, reducing version conflicts.
- Streamline CI/CD: Run tests and deploys across all projects from a single pipeline.
Introduction to Turborepo
Turborepo is a modern build system that optimizes the development and build processes for monorepos. It leverages caching, parallel execution, and smart task scheduling to make builds lightning-fast. Let's get started with setting up a production-ready monorepo using Turborepo.
Step 1: Setting Up Your Monorepo
First things first, let's create your monorepo structure. We'll use Next.js with TypeScript for our projects, as it's a popular choice for web applications. Open your terminal and run the following commands:
mkdir my-monorepo
cd my-monorepo
npx create-turboThe create-turbo command initializes a new monorepo with Turborepo. It creates a default setup with a few basic folders and configuration files. Now, let's structure our projects.
Step 2: Creating Projects Within the Monorepo
In a monorepo, you can have multiple projects. Let's set up a simple Next.js application and a shared library.
npx create-next-app apps/web
mkdir packages/uiSetting Up the Next.js App
Navigate to the apps/web directory and open the package.json file. Add TypeScript support if it's not already there:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"tsc": "tsc --noEmit"
},
"dependencies": {
"next": "latest",
"react": "latest",
"react-dom": "latest"
},
"devDependencies": {
"typescript": "latest",
"@types/react": "latest",
"@types/node": "latest"
}
}Creating a Shared Library
Move to the packages/ui folder and initialize a new library:
cd packages/ui
npm init -yNow, create a simple Button component:
// packages/ui/src/Button.tsx
type ButtonProps = {
label: string;
onClick: () => void;
};
const Button = ({ label, onClick }: ButtonProps) => {
return (
<button onClick={onClick}>
{label}
</button>
);
};
export default Button;Don't forget to add TypeScript configuration here too. Create a tsconfig.json:
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"jsx": "react-jsx",
"declaration": true,
"outDir": "dist",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}Step 3: Configuring Turborepo
With our basic structure in place, it's time to configure Turborepo. Open the turbo.json file at the root of your monorepo:
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"lint": {},
"test": {}
}
}This configuration tells Turborepo to build each project, respecting dependencies, and cache the outputs for faster subsequent builds.
Step 4: Running and Testing
To test everything is working, return to the root directory of your monorepo and run:
npm run buildTurborepo should build all projects, leveraging caching for efficiency. You can also run the Next.js app:
cd apps/web
npm run devVisit http://localhost:3000 to see your application in action. Use the shared Button component from the ui package to verify that everything is interconnected.
Step 5: Advanced Configuration
Adding More Projects
To add more projects, simply create new folders under apps/ or packages/ and configure them similarly. Turborepo will handle the rest, ensuring dependencies are correctly managed.
Customizing the Build Process
Turborepo allows customization of the build pipeline. For instance, you can add custom scripts for testing or linting:
{
"pipeline": {
"build": {},
"lint": {
"dependsOn": ["^lint"]
},
"test": {
"dependsOn": ["^test"]
}
}
}Setting Up CI/CD
Integrating your monorepo with CI/CD is straightforward. Most CI/CD platforms, like GitHub Actions or GitLab CI, can execute Turborepo commands. Create a .github/workflows/ci.yml file for GitHub Actions as an example:
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm install
- run: npm run buildConclusion
And there you have it! You've set up a production-ready monorepo using Turborepo. With this powerful tool, you can manage multiple projects with ease, speeding up your development and build processes. Remember, the key to mastering monorepos is to keep your projects organized and configurations consistent.
Now, go forth and build amazing things! Whether you're an indie hacker or part of a larger team, Turborepo can help streamline your workflow and boost productivity. If you have any questions or run into issues, feel free to leave a comment below or reach out on Twitter. Happy hacking!
Tags
Enjoyed this article?
Subscribe to get notified when I publish new posts about building products, coding, and indie hacking.
Subscribe to newsletter
