The Stack I Didn't Plan: From HTML to Next.js (And Why SEO Drove Every Decision)
Article content
My current stack — Next.js, Firebase, Vercel, Tailwind, Yarn 4 — wasn't designed. It evolved. I didn't sit down and architect it from first principles; each tool replaced something that wasn't cutting it anymore, and the thing that kept forcing my hand each time was the same requirement: SEO, and the ability to give marketing teams a foundation they could actually work on top of.
Here's how it happened.
Chapter 1: HTML and CSS — The Foundation That Never Goes Stale
I started where most frontend developers start: HTML, CSS, and a healthy obsession with getting things to look right in the browser. No frameworks, no build tools, no node_modules folder eating your hard drive.
This phase gets dismissed in career retrospectives, but I think it's underrated. Understanding the DOM at the level where you're writing it by hand — knowing what a section versus a div actually means semantically, understanding how the cascade works before utility classes abstract it away — that's not a phase you leave behind. It's the layer everything else sits on.
The limitation is obvious: static HTML can't do anything dynamic. You can't fetch data, you can't respond to a user, you can't build anything that changes. That limitation pushed me to the next step.
Chapter 2: PHP and WordPress — Adapting to the Culture
I didn't choose PHP because I thought it was the right tool. I chose it because the market was WordPress, and WordPress was PHP, and clients wanted WordPress.
That's an honest reason. It's also, looking back, a legitimate one. The industry at the time ran on PHP. Adapting to that wasn't a compromise — it was a pragmatic decision that kept me employed and exposed me to server-side rendering before it became a fashionable React concept.
What PHP actually taught me: how the server shapes what the browser receives. Request comes in, server processes it, HTML goes back out. That mental model — even though the implementation was messy — is exactly what I needed later when Next.js introduced server components and ISR. I already understood the underlying idea.
The honest downside: PHP templating in a WordPress context is one of the more unpleasant developer experiences I've had. Mixing logic and presentation in .php files, fighting with the plugin ecosystem, debugging things that shouldn't need debugging. I was ready to leave the moment I had a reason to.
Chapter 3: GatsbyJS — Where JavaScript Finally Clicked
GatsbyJS was the turning point.
I came to Gatsby because a project needed performance that WordPress couldn't deliver and a developer experience that PHP couldn't offer. Gatsby gave me React for the first time in a production context, and it also gave me something I hadn't had before: a build process that felt modern.
The JAMstack idea — build everything at compile time, deploy static files to a CDN, query APIs at build or runtime — made intuitive sense. Pages loaded fast. Lighthouse scores were good. Deploys were simple. And React, once it clicked, felt like it couldn't be un-clicked. Component thinking, props, state — it mapped to how I already thought about UI.
From an SEO perspective, Gatsby was a meaningful step up from WordPress. Pre-rendered HTML meant crawlers got real content immediately. You could control your meta tags, structure your data cleanly, ship lean HTML. For mostly static content — a marketing site, a blog, a portfolio — it was genuinely good.
But Gatsby has a ceiling. Everything is build-time. If your content changes, you rebuild. If you need to render something based on a logged-in user, or fetch live data per request, or serve different content to different visitors, you're fighting the framework. That ceiling is where I hit it.
Chapter 4: Next.js — The Landing Spot
The move to Next.js wasn't dramatic. It was the answer to a simple question: what if I want SSR and SSG and API routes and ISR — in one framework, without configuration overhead?
Next.js answered that question.
What made it the right choice for how I work specifically is the SEO control it gives you. Not just meta tags — though the Metadata API in the App Router is excellent — but the full picture: server-side rendered pages that crawlers can index immediately, Incremental Static Regeneration so content stays fresh without a full rebuild, JSON-LD structured data rendered server-side so it's always in the initial HTML, dynamic OG images via the Image Response API, and API routes that let marketing teams connect their analytics and tracking tools without needing a separate backend.
That last point matters more than people realise. When a marketing team asks "can we add this tracking script?" or "can we implement server-side GTM?" — on a Next.js foundation, the answer is almost always yes, and it's clean. On a framework that doesn't give you server control, you're either saying no or hacking it in.
The App Router shift in Next.js 13 onwards changed how I think about rendering at a more fundamental level. The server/client component boundary forces you to be deliberate about what runs where. That deliberateness has made me write better code, not just faster code.
Chapter 5: Firebase — The Google Ecosystem Decision
Firebase wasn't a researched choice. I was already in the Google ecosystem — Gmail, Google Workspace, GCP — and Firebase felt like the natural extension.
That's a real reason and I'm not embarrassed by it. Ecosystem coherence reduces cognitive overhead. When your auth, your database, your storage, and your analytics all live in one console with one billing account, that's a meaningful DX win for an independent developer or small team.
After working with it extensively: the strengths are real. Firestore's real-time capabilities are genuinely impressive. Firebase Auth handles OAuth, magic links, and session management without you having to think about it. The SDKs are well-maintained. For small-to-medium projects with variable traffic, the serverless pricing model works.
The honest watch-outs: Firestore's query model will frustrate you the first time you need a join. You'll learn to think in subcollections and denormalisation, which is a different mental model from relational databases. And at scale, costs can climb faster than expected if you're not careful with reads.
Would I pick it again? Yes — for the right project. For a project that needs relational queries at scale, I'd reach for something else. But for what I build most often, Firebase fits.
Chapter 6: Vercel — What Frictionless Deployment Actually Unlocks
The pitch for Vercel is simple: git push and you're deployed. Preview URLs for every branch. Production deployments in seconds.
What's harder to explain until you've experienced it is what that frictionlessness unlocks. When deployment is trivial, you stop batching changes. You ship smaller things more often. You share preview URLs with clients mid-build instead of waiting for a "finished" version. The feedback loop compresses, and the quality of what ships goes up.
For Next.js specifically, Vercel's platform optimisations — Edge Network, Image Optimisation, Analytics — remove a category of performance work that I'd otherwise have to configure myself. That's time redirected into building features.
Chapter 7: Tailwind and Yarn 4 — The Honest Quick Takes
Tailwind CSS: Utility-first felt wrong for about a week. Then I stopped fighting it. The velocity once you know the system is genuinely different — you're not context-switching between a .tsx file and a .css file, you're not naming things that don't need names, and your design constraints are enforced at the authoring level. I wouldn't go back.
Yarn 4: Faster installs than npm, better monorepo workspace support, stricter dependency resolution that catches problems earlier. The upgrade from Yarn 1 (which is what most projects were still using) was worth the migration cost. Zero drama after the initial setup.
What I'd Tell Someone Starting Out
Don't start with the stack. Start with the problem.
I didn't plan to use Next.js. I used HTML because I was learning. I used PHP because the market was PHP. I used Gatsby because I needed performance and a better DX. I used Next.js because Gatsby couldn't do what my projects needed. Each step was a response to a real constraint, not a trend.
The stack I have now is one I know deeply — its edges, its limits, its strengths. That depth is worth more than knowing five stacks shallowly. When something breaks at 11pm before a client presentation, you want familiarity, not options.
The through-line for me has always been SEO and enabling marketing teams to do their work without engineering bottlenecks. Every framework decision eventually came back to that. If you have your own through-line — performance, accessibility, real-time UX, whatever it is — let that drive the decisions. The stack will follow.
Sources & References
Next.js Documentation — Official framework docs covering App Router, Metadata API, ISR, and server components
GatsbyJS — JAMstack static site generator; foundational reading for understanding build-time rendering
Firebase Documentation — Google's platform docs for Firestore, Auth, and Storage
Vercel Platform Docs — Deployment, Edge Network, and Next.js-specific optimisations
Tailwind CSS Documentation — Utility-first CSS framework reference
Yarn 4 Release Notes — Package manager changelog covering the Berry release and workspace improvements
Suggested Reading
Architectural Note:This platform serves as a live research laboratory exploring the future of Agentic Web Engineering. While the technical architecture, topic curation, and professional history are directed and verified by Maas Mirzaa, the technical research, drafting, and code execution for this post were augmented by AI Agents. This synthesis demonstrates a high-velocity workflow where human architectural vision is multiplied by AI-powered execution.