Tips and pitfalls of setting up a monorepo with Turbo, Nextjs, and Vercel
![Erik Mellum](/assets/images/team/erik-avatar.gif)
![Erik Mellum](/assets/images/team/erik-avatar.gif)
Monorepos in 2022
You may have already noticed but Monorepos are trending. They offer efficiency benefits can be hard to appreciate until you have experienced them. For example, was making a CI change at my company. I had to open 15 pull requests, one for each project. In every case I was adding a single line to a .yml file. Fifteen. Pull. Requests. In a monorepo this pipeline would have been a shared file. It would have been a single pull request with a single line.
Monorepos include many other benefits, but there are also some new challenges. Deployment and tooling become harder. Turborepo is a tool I have been using to manage my monorepo for Rune. I'm happy with the results. Now I can easily build, test, lint, pretty, or dev all of my projects simultaneously. I would like to share some of the tips and pitfalls. The described monorepo uses:
- Turborepo
- Yarn workspaces
- Vercel for deploys
- Next.js
Overview
This post is for people who manage multiple projects. You may be using separate repos right now, working on a monorepo, or debugging a problem. In my case, I have Next.js projects for blog, marketing, app, store, chat server, and shared components.
Basic setup
To set up Turbo just follow the guides below.
Yarn Workspaces
I prefer yarn to npm for many reasons, but you can also use npm workspaces.
Yarn workspaces can be set up by following this guide: https://classic.yarnpkg.com/lang/en/docs/workspaces/
Turborepo
Turborepo was straightforward to set up. I was just using a simple Makefile before switching to Turbo. I was pleased with the improvements, particularly I think the remote cache is fantastic.
Begin by following this guide: https://turborepo.org/docs/getting-started
Vercel Monorepo
I highly recommend deploying your monorepo with Vercel. They make it extremely convenient. Don't skip the Ignored builds step. Keep in mind it's relative to the defined project root. There is a limit of 3 projects on the free plan for monorepo.
Set up your projects according to this guide: https://vercel.com/docs/concepts/git/monorepos
Thoughts
Packages vs symlinks
Before Turbo I was using a shared folder that I symlinked into various projects. This allowed me to share components. I switched shared folder to a package and used paths
property in tsconfig.json to allow easier importing. However the downside I encountered was that intellisense no longer was able to auto import or click into packages. This was a downside that disappointed me. I am going to continue investigating the pakage path to see how to mitigate these downsides. I noticed they are present in the ecommerce example from nextjs as well.
Gotchas
Cryptic Type Errors due to yarn workspaces
When we switched to workspaces we began seeing errors related to types that weren't even dependencies in our project. Example:
Type error: Cannot find type definition file for '__mocks__'. The file is in the program because: Entry point for implicit type library '__mocks__' error Command failed with exit code 1.
This was easy enough to fix once you knew what to do. Add this to your tsconfig.json
:
"compilerOptions { ... "typeRoots": ["node_modules/@types"] }
Dangerous warnings due to yarn workspaces
When switching to yarn workspaces you need to keep an eye out for warnings, especially at the beginning. There is a chance for packages to collide with each other if you have not specified a specific version. This error cost me a day. Everything worked fine locally, but deploying on Vercel would fail with an error that I did not realize was due to this warning.
warning Pattern ["next@latest"] is trying to unpack in the same destination "/vercel/.cache/yarn/v6/npm-next-12.1.5-7a07687579ddce61ee519493e1c178d83abac063-integrity/node_modules/next" as pattern ["next@^12.0.8","next@^12.0.8","next@^12.0.8","next@^12.0.8"]. This could result in non-deterministic behavior, skipping.
The error I saw in Vercel console:
Error: `pages/404` can not have getInitialProps/getServerSideProps
The solution was to simply change a dependency in my other projects from:
next@latest
to ^12.0.8
Errant warnings using JSX components
I received some errors relating to JSX components mounting. I suspect these were also caused by the warning above. However, these ones did have the ability to resolve by pinning a version.
'Component' cannot be used as a JSX component
Resolutions and overrides:
"resolutions": { "@types/react": "^17.0.1", "@types/react-dom": "^17.0.2" }, "overrides": { "@types/react": "^17.0.1", "@types/react-dom": "^17.0.2" }
Resources
If you want to peruse my sources they can be seen below:
From the blog
Come see what we're up to. We are excited to add new content regularly. We write content about new technologies, new products, and new business opportunities.
Test Deployment
Erik Mellum
Do you embrace change or fear it?
Erik Mellum
Six reasons dropbox paper is better than notion
Erik Mellum
Why you should estimate development tasks not stories
Erik Mellum
How to grow your career as a software developer
Erik Mellum
Resource based planning for product and engineering teams
Erik Mellum
Tips and pitfalls of setting up a monorepo with Turbo, Nextjs, and Vercel
Erik Mellum
Best practices any team can use with their typescript projects
Erik Mellum
How to Implement Invisible Captcha with Next.js in 2022
Erik Mellum
Where Do Computer Viruses Come From?
Erik Mellum
Rune Launches in Chico
Erik Mellum
Why Do Computers Break?
Erik Mellum