architecture

We didn't need to build an SSR framework

When I joined Sheypoor, the frontend was built on a custom server-side rendering framework that had been under development for more than a year. It was also contributing significantly to an SEO problem that was draining the business. We decided to stop investing in it and rewrite the affected pages with Next.js. This essay is not about Next.js. It's about the judgment call underneath that decision.

A year of investment, and the problem was still there

The custom SSR framework wasn't a bad idea, and it wasn't badly built. That's what makes this story worth telling. Someone looked at the product's needs, decided existing tools weren't enough, and committed real effort — more than a year of it — to building something tailored.

By the time I arrived, the evidence had turned: the implementation was contributing significantly to the SEO problems that were part of a significant, ongoing traffic decline. The framework had become both the infrastructure and the problem.

The question ownership has to answer

Engineering ownership is valuable when it creates differentiation. If owning a piece of the stack makes your product meaningfully better — faster, more reliable, harder to copy — then build it, maintain it, and be proud of it.

But ownership for its own sake becomes a distraction from the product. Nobody chooses your classifieds platform because its rendering layer is bespoke. The test I now apply:

For an SSR framework at a marketplace, every answer pointed the same direction. We are not in the business of building an SSR framework. Our job is to create value for customers, not to reinvent infrastructure that a mature open-source ecosystem already provides better than we ever would.

Stop investing in the custom framework. Rewrite the affected SSR pages with Next.js.

Why: more than a year of investment had not resolved the SEO contribution, and continuing meant choosing sunk-cost pride over the product. The rewrite was a team effort across Frontend and Core; roughly 20+ days after launch, Core Web Vitals were passing across the board.

What this is not

This is not an argument that Next.js is better than whatever you've built. If your custom layer passes the three questions above — if it differentiates and the ecosystem genuinely can't serve you — then owning it is correct, and adopting a framework might be the distraction. The mistake isn't building; it's building without periodically re-asking why.

It's also not an argument that the original decision was foolish. Contexts change. What was defensible in year one of a framework can be indefensible in year two, once the evidence has had time to accumulate. Good engineering judgment includes knowing when the ground has shifted under an old decision — and acting on it without defending the sunk cost.

Build what differentiates you. Adopt what merely powers you. And re-ask the question every year, because the answer moves.

The harder part: retiring your own work

The technically interesting part of this decision was small. The hard part was human: the framework represented more than a year of somebody's best work. Retiring it meant telling colleagues — some of whom built it — that the organisation was moving on. That deserved care, and it got care: the rewrite was framed as what it was, a business decision about where the organisation's finite ownership budget should go, not a verdict on anyone's craftsmanship.

Leaders ask teams to make judgment calls like this all the time. It goes better when the organisation can tell the difference between "this code failed" and "this code no longer justifies its cost".