Converting a NextJS app to mono-repo using turbo-repo

Mohit Mehta,NextJSTurbo repo

Recently, I wanted to convert my portfolio repository to a mono-repo using turbo-repo. I wanted to convert the NextJS app to turbo-repo so that I could build multiple apps in the same repo which can share packages among them.

You can check the starter source code here: (opens in a new tab), this is deployed to After converting this to a mono-repo I can deploy the apps to:

Why turbo?

turbo (opens in a new tab) is an incremental bundler and build system optimized for JavaScript and TypeScript, written in Rust.

It consists of 2 parts:

Jared Palmer, who is also the creator of Formik, built Turbo, and Vercel acquired it in 2021.

I’ve written this guide to help others convert their project into a mono repo.

Let's begin:

Clone the repository (opens in a new tab) and install the dependencies using pnpm install and then run the application to check if everything is working fine, run the app using pnpm dev. You should see something like this

My PortFolio Image

Next Step: Stop the server and continue

Adding Turborepo

pnpm add turbo --global

the next step is to add turbo.json file in the root directory of the project:

	"$schema": "",
	"pipeline": {
		"build": {
			"outputs": [".next/**", "!.next/cache/**"]
		"lint": {}

We can now run turbo dev to run the app

turbo dev

If everything was successful, you should see a similar output:

Terminal Output

Convert the project to monorepo

To convert our single project to a monorepo, we need three steps:

  1. Move our single app to an apps folder, where our web applications will be
  2. Define our workspace by creating a package.json in the root folder
  3. Create a packages folder. That's where we'll put our shared components and logic

Move our single app to the apps folder

Run the following commands in the root folder of our project:

# create the directory
 mkdir -p ./apps/website
# move the directory
mv ./** ./.** ./apps/website

The error shown below is because the git bash is not running as an Administrator.

mv: cannot move './apps' to a subdirectory of itself, './apps/website/apps'
mv: cannot move './components' to './apps/website/components': Permission denied
mv: cannot move './node_modules' to './apps/website/node_modules': Permission denied
mv: cannot move './.git' to './apps/website/.git': Permission denied
mv: cannot move './.next' to './apps/website/.next': Permission denied

Terminal screenshot

you might see the above error in Windows, to resolve this, run the git bash as an Administrator and close the current VS Code window.

Now you should see something like this. Terminal screenshot

The current folder structure will look like this:

Folder structure

Now let's move back the .git folder, .gitignore and .turbo files

mv ./apps/website/.git ./apps/website/.gitignore ./apps/website/.turbo ./apps/website/turbo.json ./

The current folder structure looks like this:

Folder structure

Create package.json in the root folder

	"name": "",
	"version": "0.1.0",
	"private": true,
	"packageManager": "pnpm@6.14.1",
	"scripts": {
		"dev": "turbo dev"

Add the workspace config:


    - "apps/*"
    - "packages/*"

Create the packages folder:

We’d now want to create the packages folder to put our shared components in. Run this command to create it:

mkdir -p packages/ui/components

Run pnpm init inside the ui folder.

create package

We will continue working on this ui package later. For now, we will focus on building a blogs app using Nextra.

Let's create a new app in the apps folder by using the following command:

mkdir -p ./apps/blogs
# create `package.json`
pnpm init
# add the dependencies
pnpm add next react react-dom nextra nextra-theme-blog

Create the following next.config.js file in your blogs directory:

const withNextra = require("nextra")({
	theme: "nextra-theme-blog",
	themeConfig: "./theme.config.jsx",
module.exports = withNextra();
// If you have other Next.js configurations, you can pass them as the parameter:
// module.exports = withNextra({ /* other next.js config */ })

create the corresponding theme.config.jsx file in your blog's directory. This will be used to configure the Nextra Blog theme:

export default {
	footer: <p>MIT 2023 © Nextra.</p>,
	head: ({ title, meta }) => (
			{meta.description && (
				<meta name="description" content={meta.description} />
			{meta.tag && <meta name="keywords" content={meta.tag} />}
			{ && <meta name="author" content={} />}
	readMore: "Read More →",
	postFooter: null,
	darkMode: false,
	navs: [
			url: "",
			name: "Nextra",

Inside pages create an index.mdx file with the content you want.

Update the turbo.json with the following:

	"$schema": "",
	"globalDependencies": ["**/.env.*local"],
	"pipeline": {
		"build": {
			"dependsOn": ["^build"],
			"outputs": [".next/**", "!.next/cache/**"]
		"lint": {},
		"dev": {
			"cache": false,
			"persistent": true

If everything is fine: you should be able to see this in the terminal after running pnpm dev:

Running the repo apps Open the URL in the browser: http://localhost:3000/ (opens in a new tab)

Running localhost:3000

http://localhost:3001 (opens in a new tab)

Running localhost:3000

Great it's working. Congratulations 🎉🎊 you have successfully completed the migration.

The final code is present here: (opens in a new tab) The deployed link:

Note: Please Update the .gitignore file to ignore the node_modules and .next folder


# See for more about ignoring files.

# dependencies

# testing

# next.js

# production

# misc

# debug

# local env files

# vercel

# typescript

Bonus: Updating the Vercel deployment settings:

Go to Project Settings in Vercel dashboard:

Project Settings in vercel

Update the Build command to:

cd ../.. && turbo run build --filter={apps/website}...

and Root Directory to:

Root Directory in vercel

Update the Website name inside the apps/website directory package.json, name to "website".

That's it, you have deployed your app on Vercel.

You can check the Source code here: (opens in a new tab) and deployed link:

Thanks for your time. I hope this will be helpful to you guys.