
When should you not use Astro?
You should not use Astro when your project is mainly a highly interactive web application rather than a website: dashboards, editors, design tools, chat and collaboration apps, or anything where most of the screen is stateful UI that changes constantly and needs to keep that state as users move between views. In those cases, nearly the whole page would be one large client-side island, so Astro's main advantage, shipping little or no JavaScript, disappears, and you'd be working around its page-by-page model instead of benefiting from it. Astro is also a weaker fit if your team is committed to one framework's full-stack features, such as Next.js with React Server Components, or if you need a CMS or a built-in database rather than a framework.
None of this makes Astro a bad tool. It makes it a specialised one: Astro's own documentation describes it as the web framework for building content-driven websites. In this article you'll learn the situations where Astro isn't the best choice and why, the grey areas where it can still work with the right patterns, the practical trade-offs to consider before adopting it, and a simple checklist to help you decide. The examples were tested with Astro 7.4.2.
Why Astro's Strengths Have Limits
Astro's design makes three bets:
- Most of the page is static, so render it on the server and send HTML.
- Interactivity is local, so hydrate only the components that need it, as independent islands.
- Navigation is between documents, so each URL is a full page load by default (a multi-page app).
When those bets hold, as they do for blogs, docs, marketing sites and shops, you get very fast pages with little effort. When they don't, each one becomes friction. If everything is interactive, there's nothing to leave static. If components share lots of state, island boundaries get in the way. If the app should feel like one continuous session, full page loads are a step backwards. The island architecture explains these mechanics in detail.
Situations Where Astro Isn't the Best Fit
1. Application-Like Interfaces
Think of an admin dashboard, an email client, a project management board, a spreadsheet, a video editor or a design tool. The UI is almost entirely interactive: filters, drag and drop, inline editing, keyboard shortcuts, optimistic updates. Very little of the screen is static content.
You can build this inside Astro, but it usually ends up looking like this:
---
// src/pages/app/[...path].astro
import Dashboard from '../../components/Dashboard.jsx';
export const prerender = false;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Dashboard</title>
</head>
<body>
<Dashboard client:only="react">
<p slot="fallback">Loading dashboard...</p>
</Dashboard>
</body>
</html>
That works. Every URL under /app/ returns the same shell, and the React app handles its own routing. But look at what Astro is doing: it serves an HTML page containing one <astro-island> with a fallback paragraph. The rendered response for /app/reports/settings was essentially:
<body>
<astro-island ... client="only" ...
><p>Loading dashboard...</p>
...</astro-island
>
</body>
All the real work, including routing, data fetching and state, happens in React. You've got a single-page app with an extra layer around it. A framework designed for applications, such as Next.js, React Router, SvelteKit or Nuxt, or a plain Vite SPA, gives you routing, data loading, mutations and client-side caching that fit this shape natively.
2. Lots of Shared Client-Side State
Islands are isolated. Each one is a separate application root, so React context, Vue's provide/inject or a Svelte context can't cross from one island to another. For a few islands that share a basket count or a theme preference, a small framework-agnostic store such as Nano Stores works well, as shown in how to share state between Astro islands.
But if your interface has dozens of components reading and writing the same complex state, with derived data and undo history, splitting it into islands creates more problems than it solves. You'll end up making one big island, which brings you back to the first case.
3. State That Must Survive Navigation Everywhere
With full page loads, in-memory state is lost each time the visitor clicks a link. Astro's <ClientRouter /> from astro:transitions softens this: it turns navigation into client-side transitions, and the transition:persist directive keeps chosen elements, such as a video or audio player, alive across pages.
That's enough for a persistent media player on a podcast site. It's not the same as an application framework where the whole component tree and its state persist by design, with nested layouts that never re-render. If your product's core experience depends on that, choose a framework built around it.
4. Real-Time and Collaborative Apps
Multiplayer editors, live chat, trading screens and collaborative whiteboards rely on WebSockets or similar connections, conflict resolution and constant UI updates. Astro can render the page and serve endpoints, and an island can open a WebSocket like any browser code. But nothing in Astro's model helps with the hard parts, and the server-first rendering it excels at hardly matters when the content changes many times a second.
5. Your Team Is Standardised on Another Full-Stack Framework
If your organisation has built its tooling, component library and conventions around Next.js, Nuxt or SvelteKit, including their data-fetching, caching and server-action patterns, introducing Astro for one more app adds a second mental model. The comparison between Astro and Next.js shows how differently they handle rendering, routing and caching. For a marketing site or docs alongside the product, Astro is often still worth it. For another product surface, consistency usually wins.
6. You Need a CMS, Not a Framework
Astro builds websites; it doesn't give editors a dashboard, roles, drafts, scheduling or media management. Non-technical teams who want to log in and publish need a CMS. You can pair Astro with a headless or Git-based CMS, which works very well, but if what you actually want is a single product that does everything, such as WordPress, a hosted site builder may be the simpler answer.
7. You Expect a Built-In Database Layer
Astro once offered @astrojs/db. It was removed in Astro 7 and is no longer maintained. The upgrade guide points to Node.js's built-in node:sqlite, Drizzle ORM or a hosted database such as Turso, PlanetScale or Neon instead. That's a perfectly good setup, but if you want a framework with an opinionated, integrated data layer, Astro deliberately doesn't provide one.
Grey Areas Where Astro Can Still Work
Some projects sound like apps but are mostly content with a few dynamic parts. Astro handles these well:
| Project | Why Astro can still fit | Tools to use |
|---|---|---|
| E-commerce storefront | Product pages are mostly static | Server islands for basket and prices, client islands for galleries |
| Marketing site with a logged-in area | Most pages are public content | On-demand rendering, middleware, sessions for the account pages |
| Docs with interactive examples | Pages are content, demos are local | Client islands with client:visible |
| Blog with comments and search | Articles are static | Islands for comments, a static search index |
| Small internal tools | A few forms and tables | Actions, endpoints and plain scripts |
A good rule is to estimate the share of each page that's genuinely interactive. If it's a small fraction, Astro is a strong choice. If it's most of the page, look elsewhere.
Practical Trade-Offs Before You Adopt Astro
Even when Astro fits, a few realities are worth knowing up front:
- Fast-moving major versions: Astro 6 (March 2026) and Astro 7 (June 2026) both included breaking changes, including the removal of legacy content collections, the stricter Rust compiler and the new default Markdown processor. Upgrades are well documented, but budget time for them. How to upgrade Astro to the latest version walks through the process.
- Plugin migration in Astro 7: Markdown now uses Sätteri. Remark and rehype plugins require installing
@astrojs/markdown-remarkand settingmarkdown.processor: unified(), or porting them. - Stricter templates: the Rust compiler rejects unclosed tags and no longer fixes invalid nesting, so sloppy HTML that used to build may now fail.
- Node.js requirement: Astro 7 needs Node.js 22.23.4 or newer, which can matter on older CI images or hosting.
- Two kinds of components: teams must learn when to write an
.astrocomponent and when to write a framework component, and that props passed to islands must be serialisable (no functions). - Build times on very large static sites: tens of thousands of pages are supported, but if content changes constantly, plan for on-demand rendering, route caching or live collections rather than rebuilding everything.
A Quick Decision Checklist
Answer these honestly:
- Is most of each page content that's the same for many visitors? If yes, Astro is a strong candidate.
- Would most interactive components work independently of each other? If yes, islands will fit.
- Is first-load performance and SEO more important than app-like navigation? If yes, Astro's MPA model is an advantage.
- Does the UI need lots of shared, persistent client state? If yes, prefer an application framework.
- Is the team already committed to another full-stack framework for this product? If yes, consistency may matter more.
- Do editors need a publishing interface? If yes, plan a CMS alongside Astro, or choose a CMS-based platform.
Mostly yes to the first three and no to the last three means Astro is likely the right tool. The reverse means it probably isn't.
FAQ: When Not to Use Astro
It can host one, by rendering a framework component with client:only on a catch-all route, but that bypasses most of what makes Astro useful. A dedicated SPA setup or an application framework is usually a better fit.
Usually not for the dashboard itself, because almost all of it is interactive and shares state. Astro is an excellent choice for the SaaS product's marketing site, blog and documentation, which many teams build separately.
Partly. With the ClientRouter, navigation happens on the client and the transition:persist directive keeps selected elements and islands alive across pages. For whole-app state persistence, an application framework is more suitable.
No. The @astrojs/db package was removed in Astro 7. Use node:sqlite, Drizzle ORM or a hosted database such as Turso, PlanetScale or Neon instead.
No, many large sites run on it, but major versions arrive regularly and include breaking changes. Pin your versions, read each upgrade guide and test builds before upgrading production.
Not necessarily. You can use React components in Astro as islands, and .astro syntax is close to HTML. The question is whether your project is content-driven, not which framework you know.
Conclusion
Astro is the wrong choice when the thing you're building is an application first: a dashboard, editor, collaborative tool or any interface where most of the screen is interactive, shares state and should persist across views. In those projects you'd wrap a single-page app in an Astro shell and gain little. It's also a weaker fit when your team is standardised on another full-stack framework, or when you really need a CMS or an integrated database rather than a framework.
For everything content-driven, from blogs and documentation to storefronts with server islands, Astro remains one of the fastest and simplest options available. Judge each project by how much of each page is truly interactive. If it's a little, use Astro; if it's nearly everything, pick a tool designed for applications, and consider Astro for the website that sits around it.


