Table of Contents
When we started building our startup, we did what most engineering teams do: we reached for the industry standard. Next.js was the obvious pick, it's backed by Vercel, has massive community adoption, and promises a "zero-config" path to production.
It took us six months to realize we were optimizing for the wrong constraints.
Our infrastructure runs on Cloudflare's edge network. Our priorities are security, speed, and keeping our small team unblocked. Next.js, for all its strengths, was creating friction in exactly those areas. So we made the call to dismantle our monolithic Next.js setup and rebuild with a modular stack: Astro + Svelte for marketing sites, Vite + React for our dashboard, and Hono for our API layer.
This post explains why we made that move, not to criticize Next.js, but to share our reasoning in case it resonates with other teams facing similar trade-offs.
1. Platform Alignment Matters More Than You Think
Next.js works best when you deploy to Vercel. That's not a controversial statement, it's a design reality. Features like Image Optimization, ISR (Incremental Static Regeneration), and the App Router's caching layers are deeply integrated with Vercel's infrastructure.
For us, running on Cloudflare meant living in translation mode. We relied on community adapters like @cloudflare/next-on-pages and OpenNext to bridge the gap. Every Next.js release brought a new round of testing to see if our deployment pipeline would hold. We were maintaining compatibility code instead of building product features.
Our new stack fits Cloudflare natively. Astro has a first-party Cloudflare adapter. Hono was literally designed for the Cloudflare Workers runtime. No shims, no adapter-of-adapter complexity. Just code that runs where we need it.
2. The App Router Added Complexity We Didn't Need
We migrated to the App Router expecting better performance. What we got was a steeper learning curve and debugging sessions that felt like archaeology.
Server Components, Server Actions, and the multi-layered caching system introduced conceptual overhead that slowed our small team down. We found ourselves tracing data hydration lifecycles and hunting "cache ghosts" issues where content would mysteriously persist or disappear due to Next.js's internal caching logic. The framework was doing too much magic, and magic becomes a liability when you need predictable behavior.
For our SaaS dashboard, we switched to Vite + React. It's a straightforward SPA behind authentication, exactly what Vite is optimized for. Hot Module Replacement (HMR) is near-instant because Vite uses native ESM and only swaps the modules that change.
The memory difference was stark. Our Next.js dev server would regularly consume 3-12GB of RAM, making it sluggish on standard development machines. Vite stays lightweight. The mental overhead dropped too, we're no longer reasoning about server-client boundaries just to render a settings page.
3. CI/CD Build Times: From 5 Minutes to Under 60 Seconds
Here's something that doesn't get enough attention in framework comparisons: the time your team spends waiting for builds to finish.
Our Next.js builds consistently took 4 to 6 minutes in CI/CD. That was the norm, not an outlier. The framework's complexity Server Component compilation, route manifest generation, image optimization pipelines, and static analysis, adds up quickly. When you're pushing multiple times a day, those 5-minute blocks compound into real productivity loss. A hotfix at 2 AM shouldn't require a coffee break.
Switching to Vite + React for our dashboard dropped build times to under 60 seconds. Vite's esbuild-based pre-bundling and Rollup production builds are aggressively optimized. There's no server-side rendering step to simulate, no complex route analysis, just efficient bundling of the code that actually runs in the browser.
Astro builds are similarly fast. Because it compiles to static HTML by default, there's no hydration graph to construct or server runtime to bundle. Our marketing site builds in roughly 30 seconds.
This isn't just about developer impatience. Faster builds mean:
When your entire deployment pipeline finishes before Next.js would have completed a single build, you notice.
4. Security: A Wake-Up Call in December 2025
The decisive moment came with CVE-2025-55182, a critical remote code execution vulnerability in React Server Components disclosed in December 2025.
This wasn't a theoretical concern. The vulnerability allowed unauthenticated attackers to execute arbitrary code via malicious HTTP requests targeting the Flight protocol used by Server Components. It carried the maximum CVSS severity of 10.0, affected default configurations, and had near-100% exploit reliability. Within days of disclosure, security researchers observed active exploitation attempts including cryptominer deployment and reverse shell installations.
For a startup handling customer data, this was a serious inflection point. The vulnerability exposed a fundamental tension in Next.js's architecture: the tight coupling between frontend hydration and backend data fetching creates a large, complex attack surface that runs by default.
Our current setup reduces that exposure. Astro generates static HTML, no runtime to exploit via request deserialization. Our dashboard is a client-side bundle that doesn't accept arbitrary server payloads. Our API layer (Hono) handles authentication and data access without any knowledge of React's internal protocols. The separation of concerns isn't just architectural cleanliness; it's a security boundary.
5. Performance: Zero JavaScript by Default
Next.js ships React to the client even for pages with minimal interactivity. That's fine for applications, but overkill for content.
We've been using Astro since version 2. Its "Islands Architecture" means we ship 100% static HTML by default, only hydrating components that actually need interactivity. When we need a complex signup form, we use Svelte inside an island. Svelte compiles away its runtime, producing smaller bundles than React's virtual DOM approach.
The numbers back this up. Astro sites ship significantly less JavaScript than equivalent React applications, with measurable improvements in load times. Our landing pages hit 100 Lighthouse scores without optimization gymnastics.
For our backend, Hono on Cloudflare Workers gives us edge routing with minimal overhead, while our .NET services handle heavy data processing with proper type safety. Each layer uses the right tool rather than forcing everything through a single framework's assumptions.
What We Learned
Next.js is a capable framework that serves many teams well. If you're building a heavily interactive application and deploying to Vercel, it's a solid choice.
But for our specific context, Cloudflare infrastructure, security-sensitive data, a small team that values simplicity, the "all-in-one" approach carried hidden costs. Our modular stack gives us:
We didn't leave Next.js because it's bad. We left because something else fit better. The best technology choice is the one that aligns with your actual constraints, not the one with the most GitHub stars.
About the stack:
Madusha Sandaruwan
Co-Founder & CTO
Microsoft AI and GitHub Security-certified engineer leading product delivery.