April, 2023
Turborepo can be an incredibly useful tool when you need to manage multiple projects in a single repository. This article walks through my experience of when I needed a monorepo solution and the benefits it provided.
The project was made up of two Next.js applications - one containing the admin dashboard and the other for the public facing site. Both apps would then interact with one another through a shared API, using Prisma with a PostgreSQL database.
When working on the project, two key issues became apparent:
Upon realising the problem, it was evident that a ‘true’ monorepo solution was needed to continue development in the most efficient manner. Given that the apps had already been setup with Next.js, Turborepo was the obvious choice.
Turborepo is a tool that allows you to manage multiple projects in a single repository, while still allowing you to treat each project as a stand alone app. This solved the project’s initial problems immediately, out of the box, at the same time allowing for additional benefits, such as the ability to:
Turborepo also allows for quick deployment on Vercel, making the migration even easier. Both apps could be deployed to Vercel like any other Next.js app. All that was required was to connect the repo to Vercel and then select the app to deploy from the app directory. The same repo could then be connected again to start a new Vercel project, repeating the process for each app in the monorepo.
The key aspects of a Turborepo project are:
turbo.json
file is stored along with the root package.json
file.turbo.json
file is where global dependencies (such as .env files) are stored, along with the pipeline. The pipeline specifies the commands to run for each app, as well as other scripts, such as building, testing, generating the database schema and linting.tsconfig
file, eslint
config, or a database config. As the project uses Prisma, this is where the database schema and prisma client are defined. This allows for the prisma schema and client to be shared across both apps, using the recommended singleton pattern for the PrismaClient instantiation.package.json
.turbo.json
file{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [".env"],
"pipeline": {
"build": {
"dependsOn": ["^build", "^db:generate"],
"outputs": ["dist/**", ".next/**"]
},
"lint": {
"outputs": []
},
"dev": {
"dependsOn": ["^db:generate"],
"cache": false
},
"db:generate": {
"cache": false
},
"db:push": {
"cache": false
},
"test": {
"dependsOn": ["^build", "^db:generate"]
}
}
}
Example of adding a shared component library in package.json
dependencies:
{
"dependencies": {
"shared-components": "*" // Ensure this name matches the folder name of the shared component library
}
}
I have a passion for learning new technologies and building applications. I thrive working in fast-paced environments, solving challenging problems and building high quality user experiences.
See more on my GitHub, Twitter or email me on 'hello' at this domain.