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: https://github.com/himohitmehta/himohit.me/tree/before-turbo-repo, this is deployed to himohit.me. After converting this to a mono-repo I can deploy the apps to:
Why turbo?
turbo is an incremental bundler and build system optimized for JavaScript and TypeScript, written in Rust.
It consists of 2 parts:
- Turborepo: A CLI tool that runs on your machine and is responsible for building your project.
- Turbopack: an incremental bundler (the successor to Webpack)
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 https://github.com/himohitmehta/himohit.me/tree/before-turbo-repo 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
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": "https://turbo.build/schema.json",
"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:
Convert the project to monorepo
To convert our single project to a monorepo, we need three steps:
- Move our single app to an apps folder, where our web applications will be
- Define our workspace by creating a package.json in the root folder
- 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
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
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.
The current folder structure will look like this:
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:
Create package.json
in the root folder
{
"name": "himohit.me",
"version": "0.1.0",
"private": true,
"packageManager": "pnpm@6.14.1",
"scripts": {
"dev": "turbo dev"
}
}
Add the workspace config:
pnpm-workspace.yaml
packages:
- "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.
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.author && <meta name="author" content={meta.author} />}
</>
),
readMore: 'Read More →',
postFooter: null,
darkMode: false,
navs: [
{
url: 'https://github.com/shuding/nextra',
name: 'Nextra'
}
]
}
Inside pages
create an index.mdx
file with the content you want.
Update the turbo.json
with the following:
{
"$schema": "https://turbo.build/schema.json",
"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
:
Open the URL in the browser:
http://localhost:3000/
Great it's working. Congratulations 🎉🎊 you have successfully completed the migration.
The final code is present here: https://github.com/himohitmehta/himohit.me/tree/after-turbo-repo
The deployed link: himohit.me
Note: Please Update the
.gitignore
file to ignore thenode_modules
and.next
folder
.gitignore
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
.turbo
Bonus: Updating the Vercel deployment settings:
Go to Project Settings
in Vercel dashboard:
Update the Build command to:
cd ../.. && turbo run build --filter={apps/website}...
and Root Directory
to:
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: https://github.com/himohitmehta/himohit.me and deployed link: himohit.me
Thanks for your time. I hope this will be helpful to you guys.
Top comments (2)
Can this be executed with bun and not pnpm?
I haven't tried it with bun, you can check the docs for workspaces here bun.sh/guides/install/workspaces.