I run OpenPanel.dev, an open source, privacy friendly analytics tool. So our own dashboard kind of has to feel fast. If your analytics app is slow, nobody will use it.
For a long time that dashboard ran on Next.js. I have used Next since the early days. It made SSR feel easy. You wrote some React, added getServerSideProps, shipped it, and it worked. No deep framework knowledge needed.
That version of Next was nice.
Then the App Router arrived. Then React Server Components. And everything started to feel... wrong.
How Next.js went from "nice" to "what is going on"
The idea behind RSC is clever. In practice it turned our app into a puzzle.
You get:
- components that are secretly server only or client only
- promises and Suspense sprinkled in places that are hard to follow
- caching that acts differently depending on which file you put the code in
-
middleware.tsthat does not really behave like middleware in the classic sense
The old "just works" feeling was gone. Every bug felt like a framework behavior you had not learned yet.
On top of that, Next.js became the default choice in the React world. Every big voice on X talks about it, tutorials use it by default, companies hire for it. So you feel a bit stupid even for questioning it.
But here is the problem. Nobody asks a basic question.
What kind of app are you building?
If you are building a marketing site or a mostly static e-commerce store, Next.js is amazing. SEO, images, static pages, all good.
If you are building an interactive website, that is different. You want instant navigation, predictable state, and simple data loading. Instead you get server round trips on every navigation, cache layers that act like a black box, and stack traces that go from client to server to client again.
It is not that Next.js is broken. It is just overloaded with ideas that look great in a conference talk but hurt once you have real users.
What hurt in practice at OpenPanel
Here is what it felt like day to day while building OpenPanel on Next 14.
1. Navigation was slow
Switching between pages in the dashboard felt heavier than it should. Even with prefetching. You could feel the server in every click.
2. Caching bugs out of nowhere
When you fetch data inside an RSC, Next.js decides when it should be revalidated. Sometimes it updates right away. Sometimes it doesn’t. You start throwing revalidatePath or no-store everywhere just to make it behave.
Half the time we couldn’t even tell what was cached. Was it our fetch call? Or the framework holding on to something behind the scenes?
That might be fine for a static site, but not for a live analytics dashboard...
3. Development was painful
Dev server startup: 25 to 30 seconds.
Change route: wait a few seconds for the compiler. Repeat. All day.
You want to tweak a chart, hit save, see it instantly. Instead you get to watch the progress bar and think about your life choices.
4. It felt like we were tied to Vercel
Yes, you can self host Next. I know. But the whole thing is clearly designed with Vercel in mind. The DX, the docs, the examples. It all nudges you in that direction.
We run on Hetzner and lean heavily into the self hosted story, so that feeling of "this framework really wants you on Vercel" did not sit well.
At some point we realised we were fighting the tool on multiple fronts. Performance, caching, hosting. That is when we decided to try something else.
Enter TanStack Start
We picked TanStack Start because it promised something boring that we actually wanted.
Simple routing. Clear data loading. No hidden magic.
It feels like React from before everything tried to be clever. You get file based routing, nested layouts, data loaders and type safety, without any mystery layers that silently cache or run on the server unless you tell them not to.
And it is fast.
Same project, new stack:
- dev server spins up in about 2 seconds
- page changes in development feel instant
- navigation in production is snappy, like a proper SPA
We did the migration in a couple of weeks. Not full time, just squeezing it in while shipping other stuff. Most of the work was not even TanStack itself. We used the chance to:
- upgrade a pile of outdated packages
- move everything from CommonJS to ESM
- clean up some old layout and routing hacks from the Next days
Moving the actual pages and routes was surprisingly straightforward.
Now the OpenPanel dashboard loads way faster and, more important, it feels predictable again. When something is slow or broken, it is our code, not some invisible cache layer or server boundary.
So when does this actually matter for you
If you are building:
- a blog
- a marketing page
- a brochure style site
- a simple shop
Stay on Next.js. Seriously. It is great for those things. You get SEO, image optimisation, static exports, all the goodies.
If you are building:
- a dashboard
- a complex tool
- something where users click around a lot and expect instant feedback
Then at least try TanStack Start on a side project. Feel the difference.
TanStack is getting a lot of attention lately, and for good reason. The team moves fast, the community is growing, and it already has solid backing from sponsors. But it still feels grounded. You can actually read the code and understand what’s happening.
What you get is a simple mental model, strong TypeScript support, and performance that feels like old school React apps where you just shipped a bundle and called it a day.
That is why we switched. Not to be trendy. Not to be contrarian. Just to make OpenPanel nicer to work in and nicer to use.
If Next.js currently feels like a puzzle you never signed up for, you are not alone. There is a simpler option. And for us, TanStack Start has been exactly that.
If you have any questions, don't be shy, I'll try to answer them the best I can.
Top comments (1)
You didn't provide a link, tanstack.com/start/latest.
It is in release candidate status, so I would not use it for critical projects.
About Next, the title of the Next site homepage is "Next by Vercel", that should give you a clue.
The biggest problem I have with Next, and Nuxt and other web UI related backends, is that it are one trick ponies. A backend framework should be web UI agnostic.
The changes like server components are not a bad thing. I think it happens too often when using universal functions that they expose too much.