Building a Better Monorepo with TypeScript, Turborepo, or Nx
Introduction
Monorepo is a software development strategy that creates shared libraries and dependencies in a single repository. Monorepos offers a solution for crucial dependency management by centralizing codebases, improving collaboration, and streamlining dependency management.
This article aims to explain the process of creating monorepos using well-known tools and technologies like TypeScript, Turborepo, and Nx, allowing you to choose the best tool based on your requirements.
Why Monorepo?
Imagine managing three separate applications for a project: a Web App, a Mobile App, and an Admin Panel. Each resides in its git repository and shares a common UI component library. Now think, when you need to update a critical button component for accessibility.
The process becomes a headache:
Update the component library and publish to NPM
Update each application one by one
Deal with version conflicts and dependencies
Ensure consistency across all projects
Sounds frustrating, right? This is where monorepos comes in—a simpler approach where all your projects live under one roof, making it easier to coordinate changes and maintain consistency across your codebase.
Let’s start with monorepos…
In the following sections, we will create basic utils monorepo which can be used anywhere in the project.
Monorepo with Typescript
In this section, we will build a monorepo manually using just TypeScript and npm.
Initialize the Project
- Create a monorepo example directory and set the root project using the below commands,
npm init -y
npm install typescript
npm install --save-dev @types/node ts-node
Organize Packages
Create a packages
folder and a utils
directory within it to act as a shared library.
mkdir -p packages/utils
Init npm inside utils with scope @monorepo,
npm init --scope @monorepo --workspace ./packages/utils -y
packages/utils/package.json
will look like this,
{
"name": "@monorepo/utils",
"version": "1.0.0",
"main": "index.js",
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
This will also add a workspace field in the root’s package.json like below. If you have multiple monorepos, you can update workspace
using wildcards like "packages/*".
"workspaces": [
"packages/utils" or "packages/*"
]
Configure TypeScript
We need to configure typescript in both the directory root
and packages
,
npx tsc --init && cd packages/utils && npx tsc --init
You can update baseDir and rootDir in packages/utils’s tsconfig.jsonas
needed. In my case it is,
"rootDir": "./src",
"outDir": "./dist", // make sure to update main
Note: Make sure to update the main field in the package.json based on your outDir. For me, it is dist/index.js .
As we need monorepo to be referenced in other projects, we need to add composite: true in
utils/tsconfig.json
.Add utils reference in the project
root’s tscofig.json
"compilerOptions": {...},
"references": [
{"path": "./packages/utils" },
]
For module resolution and path mapping, we will add the following in the root’s tsconfig.json
"compilerOptions": {
...,
"baseUrl": "./",
"paths": {
"@monorepo/utiltest": ["packages/utils/*"],
}
},
Add and Build Code
Write a sample function in packages/utils/src/index.ts
// packages/utils/src/index.ts
export function multiply(a: number, b: number): number {
return a * b;
}
Add "build": "tsc --build"
in the root and utils package.json
scripts, then build with npm run build
.
Usage
- Import @monorepo/utils into the root file to verify the function works as expected.
npm install @monorepo/utils
- You can use the monorepo package like below,
import { multiply } from "@monorepo/utils";
const result = multiply(2, 3);
console.log(`result: ${result}`);
Yeah, You have created a basic monorepo setup. You can build as many as monorepos and use them like this.
When to Use?
Monorepo’s with only typescript is useful for small, simple projects or experimental purposes without requiring third-party tooling.
Next, let’s create monorepo with Turborepo.
Monorepo with Turborepo
Turborepo is a high-performance monorepo build tool that simplifies dependency management and speeds up builds through caching.
Follow the below steps to configure monorepo using Turborepo.
Set Up Turborepo
Install Turborepo as a dev dependency,
npm install turbo -D
- Add packageManager to each package.json to ensure compatibility with Turborepo.
"packageManager": "npm@<npm-version>",
Configure Turborepo
Create a turbo.json
in the root directory:
{
"$schema": "https://turborepo.org/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false
}
}
}
The tasks
section defines tasks like build
dependencies and caching behavior.
Add and Build Code
Add a
data-transform
package to illustrate Turborepo's dependency management.Add code for transforming data in
data-transform
,
export function transformData(data: any): any {
return data.map((item) => ({ ...item, transformed: true }));
}
Build the entire project using,
npx turbo run build
- Turborepo automatically caches results, speeding up subsequent builds.
Usage
You can install @monorepo/data-transform
into the root or utils package, and verify it's working as expected.
When to Use?
Ideal for mid-size projects that need optimized build times and clear dependency management.
Yeah! We've Successfully Built a Monorepo with TypeScript and Turborepo!
Ready to take it a step further with Nx? 🚀
Head over to our full blog to explore how to implement Monorepo with Nx and discover even more insights on effective monorepo management.
If you like what you read, be sure to hit 💖 button! — as a writer it means the world!
I encourage you to share your thoughts in the comments section below. Your input not only enriches our content but also fuels our motivation to create more valuable and informative articles for you.
Happy coding! 👋
Subscribe to my newsletter
Read articles from Canopas directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Canopas
Canopas
Unless you’re a Multimillion or a Billion dollar company, you probably don’t have a multimillion-dollar ad budget or professional Spinners. Your product needs to stand out on its own merits like App Quality, Performance, UI design, and User Experience. Most companies don't care about you, your product, and your vision or dreams. They don't give a damn about either their work helped you to get more business, revenue, users, or solving a problem. That's where CANOPAS comes into the picture. Whether you have a GREAT IDEA and you want to turn it into a DIGITAL PRODUCT. OR You need a team that can turn your NIGHTMARES into SWEET DREAMS again by improving your existing product. We help Entrepreneurs, startups, and small companies to bring their IDEA to LIFE by developing digital products for their business. We prefer using Agile and Scrum principles in project management for flexibility and rapid review cycles. We are not bound by technology. We will learn new technology if it significantly improves the performance of your app. We will solve your tech-related problems even though we are not THE EXPERT in it. And we've done it multiple times in the last 7 years. In the last seven years, we helped... A STARTUP to expand its users from 2500 to over 100000 by developing mobile apps for them. An enterprise client to redevelop their app that has 1M+ monthly paid users and 10M+ app downloads. Another enterprise client(5M+ app downloads in each store) to fix bugs and broken parts in the app and as a result, they had over 98% crash-free users. We offer a 100% MONEY BACK GUARANTEE if you don't like our work. No questions asked. Visit : https://canopas.com/blog