Next.js 16 ships Turbopack as its default bundler with faster production builds, yet developer satisfaction with the framework fell from 68% to 55% in the 2025 State of JavaScript survey, the largest drop of any library measured.
In brief:
- React Router v7 (Framework Mode) is the official successor to the discontinued standalone Remix framework, and it keeps loaders and actions and error boundaries
- A 2025 controlled study found Astro had the best First Contentful Paint (FCP) in 19 of 21 scenarios. The result supports its use for content-heavy sites
- Gatsby 5 has long-term support, but Netlify does not plan for Gatsby to be a framework innovation focus, so TanStack Start takes its slot on this list, with a Release Candidate caveat
- All five frameworks can consume Strapi 5's auto-generated REST API after you configure public-role permissions or an API token; GraphQL requires installing the official plugin
Why developers search for Next.js alternatives
The State of JavaScript 2025 meta-frameworks data recorded 303 complaints about "excessive complexity" and 70 about lock-in for Next.js in its meta-framework survey, and the survey's write-up notes its satisfaction ratio now trails category leader Astro by 39 points. Next.js remains the most used meta-framework by a wide margin: 20.8% of respondents to the Stack Overflow 2025 survey use it, and 45.5% admire it. Both things are true, which is why "should we leave?" is a harder question than the complaint threads suggest.
The Next.js 16.3 report says Turbopack disk caching is on by default and reports up to 90% less memory in next dev, though the team notes no single reduction applies to every application.
Other friction points remain open. GitHub issue #90433 documents out-of-memory crashes under standalone output at roughly two requests per second, and GitHub issue #86184 reproduces server/client hydration text mismatches on both version 15 and 16.
The React team also published a security advisory confirming React Server Components vulnerabilities that could lead to server crashes or out-of-memory exceptions. Excessive central processing unit (CPU) usage is another possible outcome.
Self-hosting is workable but uneven. The official self-hosting guide confirms image optimization works with zero configuration via next start.
The Incremental Static Regeneration (ISR) cache is stored on the local filesystem of each Next.js server instance, so multiple instances need external cache coordination, and Partial Prerendering loses its Time to First Byte (TTFB) advantage without end-to-end streaming support.
Add the uncapped pay-as-you-go pricing above the Pro plan's $20 monthly credit in Vercel pricing details, and you have the main reasons teams evaluate alternatives. The decision also depends on Next.js rendering trade-offs.
5 Next.js alternatives compared
Alternative #1: React Router v7, the successor to Remix
Remix and React Router merged. The Remix team stated in its merger announcement that what the team planned to release as Remix v3 would ship instead as React Router v7, and it now recommends starting all new projects with React Router v7. Remix v2 reached end-of-life and no longer receives security updates, while Remix 3 is a separate, pre-production project built without React. If you're evaluating a full-stack React alternative to Next.js, React Router v7 in Framework Mode is the correct name, and its docs explicitly target developers weighing Next.js, Solid Start, SvelteKit, Astro, and TanStack Start.
Everything that made Remix appealing survived the merger. Route modules export a server-side loader function for data fetching and an action for mutations, with clientLoader and clientAction variants for browser-only work. Version 7 adds generated per-route types:
// app/routes/article.$documentId.tsx
import type { Route } from "./+types/article.$documentId";
export async function loader({ params }: Route.LoaderArgs) {
const res = await fetch(`${process.env.STRAPI_URL}/api/articles/${params.documentId}`);
return res.json();
}
export default function Article({ loaderData }: Route.ComponentProps) {
return <h1>{loaderData.data.title}</h1>;
}This REST API request requires configured public-role permissions or an API token.
Error boundaries also got simpler: the error arrives as a typed prop (Route.ErrorBoundaryProps), so the useRouteError hook is no longer required in Framework Mode.
For content, loaders pair naturally with Strapi: the React Router integration page shows a server-side loader fetching /api/articles with native fetch, and the React 19 blog tutorial walks through Framework Mode end to end.
Alternative #2: Astro for content-heavy sites
Astro's islands architecture inverts the Next.js default. Per the official islands docs, Astro automatically renders every user interface (UI) component to Hypertext Markup Language (HTML) and Cascading Style Sheets (CSS) and strips out all client-side JavaScript. Interactivity is opt-in per component through hydration directives like client:load and client:visible, and Server Islands (server:defer) let you defer server-rendered fragments inside otherwise static pages.
Astro also stays framework-agnostic: React, Vue, Svelte, Solid, Preact, and Lit can share a project, which helps during gradual migrations.
The claim that Astro "scores 100 on Lighthouse" is misleading as a general statement; Astro's own performance report found no framework, Astro included, reached a median Lighthouse score above 90 in real-world conditions.
The studies report mixed results: the 2025 controlled study cited above found Astro had the best FCP in 19 of 21 scenarios, while a 2026 Astro study found Astro better on Total Blocking Time (TBT) but Next.js ahead on Largest Contentful Paint (LCP) and Speed Index. These controlled results rank the frameworks only within their specific test scenarios.
Astro 5 stabilized the Content Layer API, which loads and caches content from any source through build-time or live collections. Strapi's Astro integration page documents three approaches: a native fetch request against the REST API, the official @strapi/client software development kit (SDK), and a community-maintained Strapi Content Layer loader.
The guide to creating a custom Astro loader for Strapi covers the loader route in detail. In Astro's default static mode, a configured Strapi webhook must call a deployment hook, and the frontend hosting or continuous integration (CI) platform performs the static rebuild when Strapi content changes, per the Astro CMS docs.
Alternative #3: SvelteKit for less boilerplate
Svelte 5 rebuilt reactivity around runes. The migration guide is explicit that reactivity is now determined at runtime rather than compile time through a signal-based mechanism, so the old "compiler does everything at build time" framing no longer holds. Svelte 5 still requires less code for this example. A counter in React:
// src/components/Counter.jsx
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}The same component in Svelte 5:
<!-- src/lib/Counter.svelte -->
<script>
let count = $state(0);
</script>
<p>Count: {count}</p>
<button onclick={() => count++}>Increment</button>Note the syntax: $state declares reactive state, and events are plain properties (onclick), since the older on:click form is retained only for backwards compatibility. If you see on: syntax in a tutorial, it predates Svelte 5.
SvelteKit's data story maps cleanly onto headless CMS work. Server-only load functions in +page.server.js run exclusively on the server, which is the right place for a configured Strapi API token. Strapi's Svelte integration page includes a SvelteKit load example using the REST API plus a GraphQL query keyed on documentId, and the real estate tutorial shows a full build.
Alternative #4: Nuxt for Vue teams
Nuxt is the natural landing spot if your team already knows Vue. Nuxt discontinued Vuex integration. State management now runs through the server-side rendering (SSR)-friendly useState composable for simple shared state, with the recommended Pinia library for complex patterns.
The developer-experience pitch holds up. Nuxt auto-imports pull components from app/components/ without import statements. The same system pulls composables and utilities from app/composables/ and app/utils/.
Data fetching goes through the useFetch composable, a wrapper around useAsyncData and $fetch that handles server and client hydration correctly; calling bare $fetch in a component without useAsyncData causes double fetching.
For rendering, routeRules configuration gives you per-route control, including ISR-style and stale-while-revalidate caching, so a marketing page and an authenticated dashboard can use different strategies in one app. Recent 4.x releases added Vite 8 and Rspack 2. They also added experimental SSR streaming in the Nuxt 4.5 release notes.
On the CMS side, Strapi's Nuxt integration page demonstrates useFetch against Strapi's REST API and points to two alternatives: the @strapi/client SDK and the @nuxtjs/strapi module. That module receives nuxt-modules maintenance independently of Strapi, and its Strapi 5 default has been in place since version 2.0.0. The edge deployment guide uses Strapi in its rendering-focused implementation.
Alternative #5: TanStack Start, and why Gatsby dropped off this list
Earlier versions of this article recommended Gatsby. The evidence no longer supports that for new projects. Gatsby 5 is listed as active long-term support, Netlify announced Gatsby Cloud end-of-service, npm downloads are about 245,000 per week, and Gatsby doesn't appear in the Stack Overflow 2025 results at all.
The gatsby-source-strapi plugin still exists and claims Strapi 5 support, but it's maintained by the Gatsby User Collective, a community group, after Strapi archived the original repository. Existing Gatsby sites can keep running; the Gatsby and Strapi guide remains available for teams maintaining one. Consider another framework for a new project.
TanStack Start is still at Release Candidate stage per its own docs, so factor that into risk tolerance for production work.
It registered 15% usage in the 2025 State of React survey and drew 235 write-in mentions in the 2025 State of JS survey despite not being an official survey option.
The appeal is fully type-safe routing plus explicit server functions, with React Server Components available as an experimental opt-in and disabled by default. That explicitness may appeal if you dislike the implicit server/client boundary in Next.js.
TanStack Start's Strapi setup, currently lacking a dedicated integration, uses the auto-generated REST API inside server functions with a configured API token.
How to choose among these alternatives to Next.js
You can match the framework to the workload:
- Content-first sites: Astro. Content-focused blogs and documentation sites fit this category. The zero-JS default and Content Layer API fit this shape best, and the performance evidence above supports it.
- Data-heavy React applications with forms, mutations, and nested data: React Router v7. It has stable release status and is the closest like-for-like Next.js replacement.
- Type-safety maximalists comfortable with an RC-stage dependency: TanStack Start.
- Vue teams: Nuxt is the natural fit.
routeRulescover most rendering needs. - Bundle-size-sensitive projects targeting slow networks or low-end devices: benchmark SvelteKit and the other candidates using your own application.
Weigh where you'll host before you pick. Decide your content architecture separately from your framework; solid content modeling survives a framework swap, and the broader framework comparison guide plus the roundup of the best JavaScript frameworks can round out the shortlist.
Staying on Next.js is also a defensible call. Patterns like streaming Dynamic Zones in Next.js 16 show the framework's newer rendering features working well with headless content.
Migrating from Next.js without a full rewrite
Incremental beats big-bang. Next.js Multi-Zones routing (cross-zone links must use plain <a> tags, not <Link>) and host-level rewrites let old and new frameworks share one domain during a transition. Cloudflare Workers routes can also split traffic by path.
The official guides shorten the path. Astro publishes a dedicated Next.js migration guide that maps getStaticProps() to getCollection() and lets you keep interactive React components as islands via @astrojs/react. The SvelteKit routing model is close to 1:1 with the App Router (app/products/[id]/page.tsx becomes routes/products/[id]/+page.svelte). And if you're on Remix v2, the jump to React Router v7 is mostly a dependency update with an automated codemod: npx codemod remix/2/react-router/upgrade.
A headless CMS shrinks the migration surface because your content API doesn't change when the frontend does. If you're upgrading Strapi at the same time, Strapi 5 introduced a flattened response format (data.title instead of data.attributes.title) and addresses documents by documentId rather than numeric id, with a Strapi-Response-Format: v4 header available to ease the transition.
Pairing your next framework with Strapi 5
Whichever framework wins your evaluation, the Strapi side of the stack works the same way. Strapi generates REST endpoints for every Content-Type, but Content-Types are private by default. To give a frontend access, configure public-role permissions or create and configure an API token; keeping that token secret in server-side code or hosting configuration is the frontend application's responsibility.
GraphQL requires installing the @strapi/plugin-graphql plugin, and in production you should set its depthLimit and maxLimit explicitly since neither is capped by default. The official Strapi SDK gives you Collection Type and Single Type managers if you'd rather not hand-roll fetch calls.
And if your team is experimenting with artificial intelligence (AI)-assisted workflows, the Strapi Model Context Protocol server is now generally available: it's built in but off by default, turned on in your server config, and authenticated with admin tokens.
Choose the framework that fits your project's shape, start with one migrated route behind a proxy, and let the content API stay put while the frontend moves.







