I love to over-engineer. Most of the time it is bad but sometimes we get to build cool things. Ever since I saw GatsbyJS, I wanted to re-write everything to JAMStack whenever possible. I did save $400/year by doing so.

Next, I was able to run a programmatic SEO property with over 165,000 pageviews/mo on a $5 digital ocean droplet + Cloudflare CDN using JAMStack. Then came the problem of shipping too much JS. GatsbyJS was notorious for it. I tried to use the gatsby build plugin to remove unused javascript on the page. In the meantime, I loved using Nextjs to build dynamic web apps which shipped lesser javascript. Nextjs introduced automatic static optimization with v9, basically JAMStack.

I wanted to build a JAMStack blogging platform with all the best practices that I used for my previous SEO-focused blogs and sites. The goal was to hit a 95+ score in web.dev audit. Thus, superblog was born. As usual, I chose Nextjs to build the dashboard and Nextjs (static export) to build the client- blog saas. The biggest problem with nextjs was that the build-time was too high for building client blogs. I need to make sure that users get the best SaaS blogging platform experience instead of waiting for the build + deployment to be completed.

I tried eleventy, Hugo, and a few others. Finally decided to use elderjs (svelte-SSG) because of the super-fast build times and Zero-JS pages by default for client blogs. We can hydrate individual components if we require interactivity on the page (e.g: auto-complete search box). No CSS frameworks were used, that’s right! Lesser page size! I really loved shipping ZERO-JS and decided to build the landing page of superblog with elderjs. The result is amazing! Go ahead and visit the page: https://superblog.ai

elderjs + ssg + almost zero js

Obessesion over Zero-JS

As you can see from the above picture, the superblog landing page and client superblogs built with elderjs + SSG + zero js are blazing fast and score really high in google audit. I became really obsessed with zero-js. So much that elderjs’ DX was not good but I still stuck to it. It takes 3-secs to refresh when I make a small change in my landing page. All this endurance when I already tasted ViteJS. NextJS finally switched to SWC from babel. But I refused to leave elderjs due to zero-js + partial hydration. I realized a slight mental barrier when I needed to work on my elderjs codebase which I believe is slowing down my dev. Elderjs introduced esbuild for dev but it wasn’t too reliable.

Then I came across Astro. All the beauty of elderjs’ zero-js and partial hydration + near-instant HMR. Cherry on the top: framework agnostic (choose react/vue/svelte). But their build times are higher. Astro is working to fix the slow build process. So Astro is ruled out for client superblogs but I can still consider it for superblog.ai’s landing page. This time, I decided to use a UI framework — Chakra-UI(react) because I loved using it for superblog’s dashboard. Sadly, it doesn't work well with Astro and I don't want to use Tailwind CSS (fight me!).

Moving past Zero-JS

I want to use Chakra-UI for building my landing page because there are many ready-made components that are beautiful. I can easily build the landing page and the programmatic SEO pages. In the meantime I came across Remix — it is a pure SSR framework that ships zero-js by default. Their HMR is as good as ViteJS’. I tried to re-write superblog’s internal admin dashboard in Remix but I scrapped the idea (that is beyond the scope of this article).

So, I didn't care about shipping Zero-JS for the landing page and started building a portion of the landing page with NextJS. This is what the page looked like:

ChakraUI + Nextjs

nextjs + chakra-ui

My heart broke. I immediately deployed the nextjs+chakra starter template and found similarly disappointing results. ChakraUI + nextjs tree-shaking is not well optimized. So, I rebuilt the same in Remix.

ChakraUI + Remix

remix + chakra-ui

Remix version is better but not at all comparable to the elderjs version of the fully-loaded landing page. I tweeted the findings but later deleted them as I wasn’t well back then to answer the many questions I received.

ChakraUI + Nextjs + DisableJS

So, I thought of testing the nextjs version by removing the javascript completely. We need to add the following to the routes to disable js.

export const config = {
unstable_runtimeJS: false
nextjs + chakra-ui (js-disabled)

The web.dev audit score is much better now!

I can simply switch to a lightweight UI framework and NOT disable the JS to score very high in web.dev using NextJS. But then again, due to the obsession with ZeroJS, I’m overthinking about shipping extra js which essentially means the browser has to download more content, parse more js and render the UI => more compute. However, I will try to stick to NextJS + ChakraUI and optimize the JS version to score high.

Wishlist for a JS framework

NextJS + SSG + Zero JS + Partial Hydration + ViteJS-like HMR speed

chakra+ nextjs: https://chakra-nextjs-test.vercel.app/

chakra+ nextjs + js disabled: https://chakra-nextjs-test-no-js.vercel.app/

chakra + remix: https://chakra-remix-test.vercel.app/

Source code

P.S: I got exhausted after writing half of the article. Please excuse or ask me if I missed something :D