I’ll say right off the bat: this website has a loooong history of going overboard with its tech stack. I use this domain as a vehicle to learn new things, and given how frequently the tides turn in the frontend development waters these days, things can (and did) get messy pretty quickly.
I discovered Hugo and started using it almost four years ago (
Turning to lighter frameworks like Lit and then Preact allowed me to tell myself I was still being a minimalist while dipping my toes in the component-filled waters. I added Preact (
Enter Next.js, which caught my eye over other JS-centric SSGs (like Gatsby, 11ty, or Hexo) because it sounded like the best of both worlds. Next outputs a fully static HTML version of your site just like Hugo does and uses React to render pages dynamically (a bit like a single-page web app would behave). And once I learned how its incremental static regeneration feature works, I realized that my Hugo site was actually less static than it could be with a framework like Next! Pages like /projects, which pulls data from the GitHub API, had no actual content if you were to right-click and view source — but with Next, the project data actually exists in the static HTML initially sent by the server and is “hydrated” with the same data via React on the client-side. If you host everything on Vercel, this becomes even more seamless. (More on that later.)
My requirements for Next.js
- Page sizes remain well under 1 MB. Minus images and third-party things like Twitter embeds, of course, I think I’ve achieved this on every page — the homepage still hovers around only 512 kB in total! Being super careful when choosing dependencies (Bundlephobia is awesome, btw) and making sure not to send any server-side code to the browser can make a huge difference.
devDependenciesand consolidated build tooling. I don’t want to look at another Gulp task for as long as possible. Next’s built-in Webpack and Babel support has come in clutch here.
- Same (or better) Lighthouse scores. The heavier load of JS has certainly affected performance a bit, but any modern browser can easily keep up with any React code I’ll be using at this scale. And because of Next’s static page generation (and next-seo) nothing has changed in the realm of SEO.
Things I still miss from Hugo
- Native Markdown support with shortcodes. I’m enjoying the React-ified MDX flavor of Markdown, but wrestling with @next/mdx, next-mdx-remote, and/or mdx-bundler adds a whole new layer of
potentialbreakage. Nothing beats the native parser that comes with Hugo when it comes to convenience and compatibility.
- Pure HTML output. This is a bit of a fallacy, though, considering the number of serverless Lambda functions I ended up having.
- Knowing every corner of the frontend code and how it works. Don’t ask me to explain what the
152-c95759cd62a.jsfile you just downloaded does. Because I have no clue.
- Total and complete portability. In exchange for a lot of convenience, I accepted a bit of vendor lock-in when I put all of my eggs in Vercel’s basket. Next.js is their creation, and other hosts (including Netlify, Render, DigitalOcean, etc.) have begun adding support for some of the core functionality. But quite a few of the more exciting features (like image optimization and analytics) are clearly designed for Vercel and Vercel only.
Doing the actual migration was pretty boring and uneventful (besides the wealth of React knowledge I got to teach myself, which I’m sure is still less than 2% of what’s out there). I found the goal with the least mental friction was to build a 1:1 replica of the Hugo site with Next.js, to the point where a visitor wouldn’t have been able to tell there was a change, except for much faster page transition times. You can track how that went in this pull request and judge for yourself...