A couple months ago I wrote a blog post about adopting monorepos for code sharing across all company projects. This was great. Approximately 10K lines of code were removed after adopting this approach. Shared UI and logic got more consistent and easier to maintain. Until upgrading one of the React Native apps. Then the flexibility and complexity of this approach became apparent.
Since React Native doesn’t have first party support for modern package managers like pnpm, yarn berry or bun when used in a monorepo, there are either issues you need to work around, or you stick to yarn classic. After trying to adapt modern package managers to work in this setup, I gave up and chose to stick with yarn classic. This nearly doubled the build times for my Next.js apps on Vercel. This is not ideal, however it’s not a deal breaker.
The deal breaker came when I had to upgrade Expo to SDK52, which resulted in a React Native version mismatch. Having two React Native apps previously with matching versions was hiding this for a couple months. After rereading Expo’s guide on monorepos it does say that React Native has issues with multiple versions being installed in a single repo. This isn’t ideal of course, if the monorepo grows, you don’t want to be forced to upgrade 10 React Native apps to the latest version ever time you need to upgrade one.
So after finding out that you can’t scale a monorepo with multiple React Native apps, I decided to move the React Native apps out of it. I published code the apps depended on to npm through the monorepo and installed those in the React Native apps. The monorepo is still great for the web projects. After moving the React Native projects out, I could switch over to pnpm to cut the build times in half, and utilize pnpm’s more modern workspace tooling to more easily avoid conflicting React and Next.js versions.
What started as a solution for code sharing ended up creating more problems than it solved for React Native development. This highlights the importance of keeping things simple and not forcing things when they don’t work. Sticking with a hybrid strategy of utilizing a monorepo for web apps and splitting out the React Native apps has proven to be a more maintainable solution in the long run.
Andor Davoti - 16/12/2024