Next.js to Astro – when your project is really content.
Next.js is an excellent framework. For an application it is usually the better choice, and we will not talk anyone out of it who is building one. The honest thesis of this page is narrower: if your Next.js project is a marketing site, a docs site or a blog, you are paying the complexity and JavaScript cost of an application framework for something that is fundamentally content. Astro inverts the defaults – server rendering and static HTML by default, client JavaScript only where you explicitly ask for it. And your React components can come along.
React does not have to go
Astro is UI-framework agnostic with an official React integration. Existing components keep running as islands instead of being rewritten.
No client JavaScript by default
Astro removes all client-side JavaScript from components by default. Hydration is an opt-in per component, not a baseline.
A documented path
The Astro docs carry a migration guide for Next.js. They also note that many of those guides are stubs – so the actual work stays manual, and we treat it that way.
- Move if it is a content site. Marketing presence, documentation, blog, careers pages, landing pages: for these page types a React-everywhere model is overhead. Astro ships the same result as prerendered HTML, with interactivity only where it is actually needed.
- Stay if it is an application. Login, roles and permissions, shared client-side state across routes, a dashboard with real state: then Next.js is the better tool – and we will tell you so even when we would rather have the project.
- Your React components survive. Astro has an official React integration. An existing component library is not thrown away, it is mounted as an island – technically the most reassuring fact about this migration.
- The difference is the default, not the capability. Astro prerenders statically by default; individual routes render on demand as soon as you set
export const prerender = falseand add an adapter for your target runtime. - Read first: the sober model comparison at Astro vs Next.js. This page describes the move; that one describes the decision.
Move or stay – the dividing line is not the framework.
It is the question of whether you operate an application or publish content. Both columns are meant seriously. We have no interest in replacing a working Next.js project just because a migration would be billable.
Move to Astro when …
The symptoms are usually the same – and they sound like a framework problem while being a model problem.
- Your repository is called website, marketing or docs and still contains the full stack of an application.
- Most of your pages are static. What is interactive is a menu, a form, a filter, a pricing calculator – maybe five components in total.
- Your team regularly debates
"use client"boundaries although nobody is building an application. - Your Core Web Vitals suffer from shipped JavaScript, and optimisation means trimming framework code rather than making content arrive faster.
- Editors and marketing wait on engineering because the content model lives in props and fetch calls instead of a schema.
- The build and deploy chain has become noticeably heavier than the content it produces.
Stay on Next.js when …
Then a move is not a gain, it is an expensive rename of the same complexity.
- Your product is an application: authentication, roles, user accounts, a dashboard with genuine state.
- You need shared client-side state across routes – a cart, a filter session, a multi-step form without a reload.
- Your architecture depends on Next-specific building blocks: middleware patterns, ISR semantics, App Router server-component composition.
- Large parts of the surface are interactive rather than decoratively interactive – SPA-style navigation is part of the product promise.
- Your team lives in React, and the website is a small appendix to the product anyway.
- It works, it measures fast enough, and nobody is in pain. Then "it works" is a perfectly sufficient reason.
What actually differs, technically.
No verdicts, just the two models side by side. Almost every row describes a default – and defaults decide what a project looks like two years in.
| Dimension | Next.js | Astro |
|---|---|---|
| Rendering model | React-based. Server and client rendering interlock; the tree continues on the client. | MPA architecture with server rendering as the default – explicitly not an SPA client-side-rendering model. Every page is a page. |
| Client JavaScript | Hydration is the normal case. A baseline of framework code belongs to the delivery model; you can reduce it, you cannot configure it away. | Astro removes all client-side JavaScript from components by default. What you do not request is not shipped. |
| Interactivity | Steered per component across the client boundary; crossing it hydrates the subtree. | Islands: an island is "an enhanced UI component on an otherwise static page of HTML". Enabled per component via client:load, client:idle or client:visible. |
| Routing | File-based routing with a framework client router; navigation stays inside the running JavaScript context. | File-based routing, navigation as a normal full-page load. View transitions are built in, and <ClientRouter /> makes client-side routing an opt-in. |
| Data fetching | Anchored in the framework: server components, caching layers, revalidation. | Data is fetched at build time or while the route renders on the server. Dynamic parts can render as server islands via server:defer without blocking the first render. |
| Content modelling | Convention rather than structure: content arrives from MDX, a CMS SDK or fetch calls, typed by hand. | Content collections since Astro 2.0 – "a set of related, structurally identical data" with a Zod schema, automatic TypeScript types and query APIs such as getCollection(). |
| Hosting & adapter | Designed for server-side operation; a purely static export is possible but not the normal case. | Static is the default. On-demand rendering needs an adapter for the target runtime; official ones in the @astrojs scope: Node, Vercel, Cloudflare. |
| What it is built for | Applications on the web – and the websites around them. | Self-description: "a JavaScript web framework optimized for building fast, content-driven websites". Content-driven, server-first, fast by default. |
How a Next.js to Astro migration runs.
Seven steps. The third one is the one we get asked about most – and the one that saves the most work.
Inventory instead of gut feeling
We walk through your repository and sort the routes into three piles: purely static, static with one island, genuinely dynamic. Alongside that we pull your indexed URLs, your Core Web Vitals from field data and the list of Next-specific building blocks something depends on. The output is a recommendation – including the option not to migrate.
Define the content model before any code
What today exists as MDX files, CMS responses and hand-typed props becomes content collections with a Zod schema. Zod validates every entry at build time and provides automatic TypeScript types when you query content. From then on a missing field breaks the build, not the live site. The built-in glob() loader reads directories of Markdown, MDX, Markdoc, JSON, YAML or TOML; file() reads multiple entries from a single file.
Keep your React components and mount them as islands
The decisive step: your React components are not rewritten. Astro has an official React integration, the component gets imported into an .astro file and marked with a client:* directive. The pricing calculator gets client:load, the accordion further down client:visible, the non-critical piece client:idle. Anything without a directive renders to HTML on the server and ships zero JavaScript. Components from multiple frameworks can be combined, but only inside an .astro file – useful later if you want to add something in Svelte or Vue.
Map layouts, routes and URLs one to one
Page structure and layouts move to Astro while the URL structure stays identical. Wherever it has to change, the 301 list is written in parallel – line by line, old URL to new, written before the migration rather than after it. Titles and heading structure of the load-bearing pages stay stable so the move does not cost rankings.
Name the dynamic routes deliberately
Static is the default: without further action the entire site is prerendered. For routes that genuinely have to render on demand – form handling, personalised areas, preview mode – we set export const prerender = false and install the adapter for your target runtime. If the dynamic share dominates, output: "server" flips the default and individual pages return to prerendering with export const prerender = true.
Images, metadata, measurement
Images run through the built-in components: <Image /> sets alt, loading and decoding and infers dimensions so no cumulative layout shift appears; <Picture /> generates several formats and sizes with a fallback. Remote images have to be allowed in the configuration, images in public/ bypass processing entirely. Before launch we run Lighthouse on staging, check structured data and test every redirect.
Launch, re-measure, hand over
After go-live we watch indexation, rankings and field data for several weeks and correct where needed. You receive the repository with its full history, the accounts in your own name and a README that explains the build. When we talk about speed, we talk about your numbers before and after the migration – from your project, with your real user data.
What you lose or have to rethink.
This page would be worthless if it only listed the upside. Four things get uncomfortable in this move – and for one of them the correct answer is simply: stay.
Shared client-side state across routes
This is the hardest point. In Next.js the application keeps running in the browser while the user navigates: a cart, a filter session, a multi-step form or an audio player survive the page change because technically there is no page change. Astro is an MPA – every navigation is a normal full-page load by default. State that has to survive therefore needs a home: the URL, storage, a cookie, the server. View transitions are built in and <ClientRouter /> is "a built-in, lightweight component to enable client-side routing", which smooths transitions and helps with persistent elements – but it does not replace an application architecture. If your product depends on continuous client-side state, that is not a refactor, it is an argument against the migration.
A heavily interactive surface
Islands are explicitly designed for the case where most of the page is static HTML and interactivity is added in specific places. Once that ratio inverts – almost everything interactive and only the header not – you are working against the model. You end up with many islands, several hydration boundaries and cross-island communication that would have been trivial inside one continuous React application. The rule of thumb we apply in the first call: if you can no longer count the interactive components of your site on one hand, we look very carefully at whether we should recommend the move at all.
Next-specific building blocks
Middleware patterns, ISR semantics and App Router server-component composition are not general web concepts; they are properties of one particular framework. Astro has a path for much of it – server islands via server:defer for personalisation, export const prerender = false plus an adapter for dynamic routes, your target runtime's configuration for caching. But it is a different path, not a port. Anyone running a fine-grained revalidation strategy across thousands of routes is not migrating, they are redesigning. That is why the inventory of these dependencies sits in step one and not in the retrospective.
And if it really is an application: stay
We build custom web applications ourselves – see custom software development – which is exactly why we never need to sell Astro to anyone. One sensible middle path gets overlooked surprisingly often: the application stays in Next.js while the marketing site and the documentation move. Two repositories, two deployments, one shared domain via routing rules or subdomains. The marketing team gets a fast, editorially maintainable site, the product team keeps its stack, and nobody has to touch a working product. For the majority of enquiries that reach us on this topic, that is the right answer.
What comes with it: editing the website by chat
We do not only build with Astro, we put a modern AI stack on top of it. Concretely: your team can edit the website in a chat – for example through a Telegram bot. Change a paragraph, add a blog post, swap an image, correct a price: as a message rather than a CMS session. This works precisely because after the migration your content lives in a typed, schema-validated content model – content collections with Zod – or in a headless CMS with an API. Both are machine-addressable: an agent can only fill fields that exist, in formats that validate. A faulty edit fails in the build, not on the live site. Every change lands as a reviewable commit, with history, review and rollback. For a Next.js project whose content is scattered across props, fetch calls and hand-typed objects, that is exactly the step that was missing before.
This is not slideware: we already run a WhatsApp AI agent in production – chat agents are day-to-day work here. And because this paragraph would otherwise read like marketing, the limits belong with it: the chat route complements an editorial workflow with approval stages, it does not replace one. Editorial responsibility stays with you – an agent writes and proposes, it does not decide. Structural changes such as new page types, layouts or navigation remain development work. And the scope is defined per project: which collections, which fields, which level of approval. It suits a large enterprise with an editorial team just as well as the sole trader who will never open a CMS. What that looks like day to day is described under edit your website by chat.
Stack
Astro 7 is the current major line. Astro follows semantic versioning; extended maintenance with security fixes covers exactly one previous major. The licence is MIT.
What stays
React, your component library, your design system, your URLs, your hosting provider. Official adapters in the @astrojs scope exist for Node, Vercel and Cloudflare.
Measurement
We measure Core Web Vitals before and after the migration, with your own field data. Details under Astro performance optimization.
How long this takes – and what moves the range.
Prices deliberately stay off this page. Timelines do not, because that is what you plan around. The ranges below are our own experience for exactly the seven steps above – measured from kickoff to go-live, and assuming design and content are not being reinvented in parallel.
- Inventory: 3 to 5 working days – Walk the repository, sort routes into "purely static", "static with one island" and "genuinely dynamic", pull the indexed URLs, fetch field data, list the Next-specific dependencies. The output is a recommendation with an effort estimate – explicitly including the recommendation not to migrate.
- Contained case: 4 to 7 weeks – A docs or marketing site with up to roughly six distinct page types. Content moves across unchanged, no CMS involved, one language, a handful of interactive components, and the design stays as it is. This is the case where a move almost always pays for itself.
- Typical case: 8 to 14 weeks – A grown site with eight to fifteen page types, a connected headless CMS, two languages, several routes rendering on demand behind an adapter, plus forms, search, consent and tracking. Here it is not the page count that moves the date, it is the number of templates and integrations.
- Beyond that: phases instead of a number – Fine-grained revalidation across thousands of routes, deep middleware logic, a shop or an attached application. For those we quote no total duration; we cut the work into phases with their own sign-off. Often the first phase is only the website anyway, while the application stays on Next.js.
- After go-live: 8 to 12 weeks of watching – Indexation, positions and field data stay under observation and get corrected; redirects and Search Console get checked. That is a commitment about our attention during that window – not about your rankings. Nobody can honestly promise the latter, and anyone who does should make you suspicious.
What pushes the range up
The number of distinct templates – not the number of pages. Content that gets rewritten instead of moved. Every additional language. A CMS that has to be selected and modelled alongside. Every integration with its own contract: search, personalisation, consent, shop, marketing automation. And every Next-specific building block something depends on.
What pulls it down
Few layouts. Clean MDX instead of scattered fetch calls. Content that moves one to one. A design that stays. And one named person on your side who is allowed to decide without convening a committee.
The underrated variable
Approval cycles. Two rounds of feedback with a one-day turnaround are a week. The same two rounds with one weekly meeting and three opinions in the room are a month. This variable is not on our side of the table – which is why we write it into the plan before the project starts.
And the cost?
Stays with our usual pattern: a traceable estimate after the inventory, with its assumptions stated openly. What the number actually hangs on is written out under Astro development cost.
Get an assessment – including the answer "stay where you are".
Describe in three sentences what your Next.js project is today: marketing site, docs, product, or all of it at once. You get a reasoned assessment of whether a move is worth it – and if not, why not.
Next.js to Astro at a glance.
Nine rows for everyone who will read the rest of this page later. The last row is our opinion, not a statement of fact – and it is phrased so you can disagree with it.
| Question | Short answer |
|---|---|
| Where the move pays off | Marketing sites, documentation, blogs, careers and landing pages – anything that is content at its core and only interactive in specific places. |
| Where it does not | Applications with login, roles, shared client-side state across routes, or a surface that is interactive throughout. Then Next.js remains the better tool, and we will say so. |
| What happens to React | It stays. Astro is UI-framework agnostic with an official React integration; existing components keep running as islands and only hydrate through a client:* directive. |
| What happens to your URLs | They stay identical wherever possible. Every unavoidable change gets a 301 redirect – written before the migration, tested before go-live. |
| What changes in operations | Static HTML as the default delivery, client JavaScript only on request. On-demand rendering needs an adapter for your target runtime; the official ones in the @astrojs scope are Node, Vercel and Cloudflare. |
| How content is maintained afterwards | Content collections with a Zod schema, or a connected headless CMS – Astro is CMS-agnostic. On request also by chat, with every change landing as a reviewable commit. |
| How long it takes | Contained case 4 to 7 weeks, typical case 8 to 14 weeks, larger programmes in phases – then 8 to 12 weeks of monitoring. The variables are listed under Timeline. |
| What it costs | Not on this page, because any number before the inventory would be a guess. After the first call you get an estimate with its assumptions stated openly; the cost drivers are written out under Astro development cost. |
| Our take | Most conversations on this topic do not end at "migrate everything", they end at "the application stays, the website moves". If you run a pure content site on Next.js, the move buys you real operational simplicity. If you run an application, you are only trading one kind of complexity for another – and we would rather say that in the first call than in week six. |
Frequently asked questions about migrating Next.js to Astro.
Can we keep our React components?
Yes – and that is the single most important technical fact about this migration. Astro is UI-framework agnostic with official integrations for React, Preact, Svelte, Vue, SolidJS and Alpine.js. An existing component gets imported and mounted as an island via a client:* directive. Components from multiple frameworks can be combined, but only inside an .astro file. So your component library is not thrown away, it is used more selectively.
What happens to server components and the App Router?
The concepts are not ported, they are replaced. In Astro, server rendering is the default rather than a component property: by default the entire site is prerendered and static HTML is sent to the browser. Dynamics appear where you ask for them – via export const prerender = false plus an adapter for a route, or via server islands with server:defer for individual regions. If you have invested deeply in App Router composition, price that effort honestly before deciding.
We are still on the Pages Router. Does that make the migration easier?
Usually yes. The Pages Router sits closer to a classic page model: one file, one route, one data call per page. That is exactly what Astro maps onto – file-based routing, data fetched at build time or while the route renders on the server. It gets more expensive where nested layouts with their own loading states and server-component composition are deeply interwoven. We count those places in step one, before anyone quotes a number.
What happens to our middleware?
Middleware patterns are a property of Next.js, not a general web concept – so there is no port, there is a sort by purpose. Redirects and rewrites belong in the 301 map or in your hosting and CDN layer anyway. Personalisation can become a server island via server:defer, which renders independently on the server without blocking the first render. Gating real user accounts, on the other hand, is an application concern – and an argument for leaving that part on Next.js.
We rely on ISR. Is there an Astro equivalent to revalidation?
There is no one-to-one equivalent, and we would rather say that up front. ISR semantics are Next-specific. Astro offers three routes to the same goal: prerendered HTML that is rebuilt and deployed when content changes; individual routes with export const prerender = false plus an adapter, rendering on the server per request; and server islands via server:defer, where shell and main content are cached aggressively while personalised elements load in. If you revalidate fine-grained across thousands of routes, you are not migrating, you are redesigning.
What happens to our API routes?
They get sorted first, ported second. Endpoints that belong to the website – form handling, a webhook, a search index, a newsletter signup – follow the same pattern as any dynamic route: export const prerender = false and the adapter for your target runtime. Endpoints that belong to the application are better left where the application is, or promoted to their own service. Dragging them along because they happened to share a repository is the most common avoidable mistake in this move.
We use next/image everywhere. Do we have to touch every image?
The calls get replaced, the image files do not. Astro ships built-in image optimisation: the Image component sets alt, loading and decoding and infers dimensions so no cumulative layout shift appears; the Picture component generates several formats and sizes with a fallback. Sharp is the default image service. Two things cost time: remote images have to be allowed in the configuration, and images in public/ bypass processing entirely – the latter is often a quiet quality loss during a move if nobody looks.
Our site is bilingual. How does i18n routing work in Astro?
Each language version is its own route with its own URL prefix, and that is where the migration work sits: URL mapping per language, hreflang pairs, canonicals. The content itself we model per language in content collections; the Zod schema validates each language separately and reports missing translations in the build rather than on the live site. Honest about effort: after the number of templates, every additional language is the second biggest schedule mover. This very site runs bilingual – we know the trip hazards from operating it.
We sit in a monorepo with our application. Does Astro fit in there?
Yes. An Astro site is its own package with its own build; whether it lives in your existing monorepo next to the application or in a separate repository is an organisational decision, not a framework one. Shared React components can be imported as a workspace package, because Astro integrates React officially. The honest catch: components that assume Next-specific imports have to be rewritten at those points. How many that is becomes clear after the inventory, not before.
We host on Vercel. Do we have to move?
No. Static is the default in Astro, and prerendered HTML runs almost anywhere. For on-demand rendering there are official adapters in the @astrojs scope for Node, Vercel and Cloudflare – so you can stay, move to your own Node runtime, or go to Cloudflare. We decide that from your operational reality rather than taste: if you already have a working deployment with preview environments and a pipeline your team trusts, do not migrate it as a side quest.
Will the site be measurably faster after the migration?
That depends on how much client JavaScript your pages genuinely need. The structural difference is unambiguous: Astro removes all client-side JavaScript from components by default, whereas hydration is the normal case in the React model. We still quote no numbers until we have measured. We record your Core Web Vitals before and after the move using your own field data – someone else's benchmark says nothing about your project.
Will we lose rankings during the move?
Not if the move is planned. Before we start we pull every indexed URL, keep the URL structure identical wherever possible and write a 301 redirect for each deviation before migrating rather than afterwards. Titles, heading structure and structured data of the load-bearing pages stay stable, and the redirects are tested before go-live. After launch we watch indexation and positions for several weeks and correct where needed. There is no guarantee, and anyone offering one cannot honour it.
How long does a Next.js to Astro migration take?
Three factors set the frame, and page count is not one of them: the number of distinct page types, the depth of the content model, and how many Next-specific building blocks something depends on. As a working figure: a docs or marketing site with few layouts, one language and no CMS lands at 4 to 7 weeks; a grown site with a CMS, two languages and several dynamic routes lands at 8 to 14. Anything larger we cut into phases. Every variable is listed under Timeline.
We have 4,000 blog posts. Is there downtime during the switchover?
Your old site stays online until the new one is signed off – it is built in parallel on staging. The switch itself is a change of target with fully tested redirects, scheduled into a low-traffic hour. We do not promise zero seconds, because DNS and cache behaviour are not in our hands. On volume: content collections ship built-in caching for thousands of entries, so 4,000 posts are a build question. It only gets expensive when those 4,000 posts use twelve different layouts.
Can we migrate incrementally instead of all at once?
Yes, and it is often the more sensible route. The usual split: the application stays in Next.js while the marketing site, blog and documentation move to Astro. Two deployments under one shared domain, separated by routing rules or subdomains. The product team keeps its stack, marketing gets a site it can maintain without engineering. Within a single project we otherwise migrate page type by page type, starting with the routes that carry no interactivity.
Does a niche framework make it harder to hire developers?
The objection is fair, but it lands softer than it sounds. Most of your code stays React – you hire for that exactly as before. An .astro file is essentially HTML with a script section in front of it; in our experience someone who knows React is productive within days. TypeScript is built in, with three tsconfig presets and astro check for type checking. What stays true: a job ad saying "Next.js" gets more applications than one saying "Astro". Which is why we write the README to be understood without us.
Can we take development in-house – and what happens if we part ways?
You can, and that is arranged before it is ever needed. The repository is yours, with its full history; the accounts are in your name and the build is explained in a README. Astro is free open-source software under the MIT licence – there is no licence that expires when you change supplier. On upgrades: Astro follows semantic versioning, the current major line is Astro 7, and extended maintenance with security fixes covers exactly one previous major. A predictable rhythm – but not one you can ignore for three years.
Who is liable if something breaks after launch?
For what we built, we are. Before go-live there is a formal acceptance with a defect list; faults in our implementation are fixed within the contractually agreed warranty period at no extra invoice. Content errors, third-party outages and changes your own team ships are not part of that. Because every change is a commit, you can always trace what happened when – and roll it back. For ongoing operations there is support and maintenance as a separate agreement.
Can we maintain content without a developer afterwards?
Yes. Content then lives in content collections with a Zod schema or in a connected headless CMS – Astro is CMS-agnostic and acts purely as the presentation layer. Without a CMS your team edits Markdown directly in the repository, and the schema reports missing fields before anything deploys. On request we also set up editing by chat: change a text, add a post, swap an image as a message to a Telegram bot, every change landing as a reviewable commit. New page types and layouts remain development work.
When should we simply stay on Next.js?
When your product is an application. When shared client-side state across routes is part of the product promise. When large parts of the surface are genuinely interactive rather than decoratively interactive. And when it simply works, measures fast enough and nobody is in pain – that last criterion is the most underrated one. A migration costs time, attention and risk; it has to give back something beyond "more modern". If we do not see that in your case, that is what the recommendation will say.
Is Astro free?
Yes. Astro is free open-source software under the MIT licence; there is no licence fee for the framework itself. Costs come from development, hosting and the services you connect – from the project, in other words, not from the tool.
Who is behind Astro?
Astro is an open-source project developed in public in the withastro repository on GitHub. The licence text is MIT and the copyright in it is held by Fred K. Schott. There is no subscription and no vendor who could switch off your access.
Does Astro need a server?
By default, no: the entire site is prerendered and static HTML pages go to the browser. You only need a runtime for rendering on demand – and then an adapter comes into play, officially for Node, Vercel or Cloudflare.
Is Astro good for SEO?
The preconditions are right: server rendering as the default, static HTML in delivery, and an image component that infers dimensions and so avoids layout shift. What actually decides it is still URL continuity, content and internal linking – not the framework.
Is your Next.js project an application – or content?
Tell us briefly what is live today and where it hurts. You get an honest assessment of the move, the effort and the alternatives. Usually within 24 hours.
Request a Next.js to Astro migration.
Repository size, page types, Next-specific dependencies – three sentences are enough for a first assessment.
We usually reply within 24 hours.
Remote & on site – working across the DACH region (DE, AT, CH), with international project experience.
Related to this topic.
Astro vs Next.js
The sober model comparison – before you think about moving at all.
Learn moreAstro migration
Every migration path in one overview: WordPress, Webflow, Framer and Next.js.
Learn moreAstro performance optimization
Measure, improve and prove Core Web Vitals after launch.
Learn moreCustom software development
For when your project is an application and should stay one.
Learn moreAstro agency
Services, cost ranges and how we work in the Astro stack.
Learn moreIT project management
When the migration is part of a larger programme.
Learn more