Mono repos and SSR exploration
Published by Zach Cardoza.
For my latest project, I decided to forgo my very comfortable Vue 3/Vite stack and instead try to build a web-first server-rendered application designed for excellent SEO and minimal code shipped to the client. My search brought up many possibilities, including frameworks like Astro, NextJS, and SvelteKit. All of these had SSR or SSG options, but the hydration approach was very heavy-handed and required a large run-time to load before the hydration could take place. What's the point of using a server to pre-render if the process of moving the rendering to the client doesn't eliminate the work being performed on the client? That's when I came across Qwik and QwikCity by Builder.io.
Without going into too much detail, Qwik performs SSR similarly to the other frameworks mentioned, but the runtime is significantly smaller and there is no hydration step as the delivered code is already stateful. There are also a few other huge capabilities baked directly into the framework like the ability to use Partytown to offload other scripts onto a background thread using Web Workers. There is also middleware to run the Qwik SSR behind an Express server.
This then led to the second hurdle which was how to incorporate an RPC-style server into an SSR server utilizing the same Express server instance to reduce costs, but allow for splitting of two servers in the future if needed. With some help from a pair of podcasts (JS Party, Syntax FM) I realized that a mono repo was the solution I needed. I quickly identified Nx and TurboRepo as being the leaders in the space and spun up projects using both tools. Nx promises a much more integrated experience but I quickly ran into roadblocks with this integration as it works well for mainstream projects but support for newer frameworks (like Qwik) is not available. After a week of trying both it became obvious that TurboRepo was the more suitable solution for my needs. It falls back on npm to handle the dependency management so it works well with every package I used and the configuration is very simple. Ultimately I can see some shortcomings with its limited system as I have faced needs to do specific tasks on a subset or repos, but there is some basic support for this and I've been able to work around all the issues thus far.
In the weeks to come I hope to bring an example of a project utilizing the structure I've worked out as I do feel several pitfalls are not highlighted in the documentation for both of these projects. If there is specific interest or questions regarding either of these technologies feel free to reach out to me.