BLOG

If You Think Astro Is Just for Static Sites, You're Wrong

Dave Cilluffo ·
web developmentAstroframeworksSSR

We run a full application on Astro — authentication, database, WebSocket chat, role-based permissions. Here’s why Astro became our default for everything, not just blogs.


I’ll admit it. A year ago, if you’d told me I’d be running a real application on Astro — one with user authentication, a SQLite database, real-time WebSocket chat, role-based permissions, and an audit log — I’d have told you to use the right tool for the job. Astro is for static sites. Use Next.js for apps.

I was wrong.

TwelveTake Studios now runs over fourteen websites and a full collaboration platform on Astro. Static sites, SSR apps, and everything in between. This isn’t a contrarian take for clicks. It’s what happened when I actually tried building something real with Astro’s server mode instead of assuming it couldn’t handle it.

The Assumption Everyone Makes

Astro launched with a clear pitch: zero JavaScript by default, static-first, content-focused. And that pitch is accurate. Astro is excellent at static sites. Most of our sites — the studio website, client projects, portfolio demos, even some ARG sites for a game we’re building — are static Astro builds. HTML, CSS, done.

But somewhere along the way, “static-first” became “static-only” in people’s heads. I see it in forum posts, in framework comparison articles, in conversations with other developers. “Astro is great for blogs.” “Use Astro for your marketing site.” “If you need a real app, use Next.js.”

That framing is outdated. Astro has had SSR since version 2. By version 5, it’s mature, stable, and genuinely capable.

What We Actually Built

Let me be specific, because vague claims are worthless.

Bandmate is a collaboration platform for bands. Not a toy project. It’s deployed, it’s in use, and it handles:

  • Magic-link authentication — no passwords stored, email-based login with secure tokens
  • Role-based permissions — admin, manager, member roles with granular access control
  • SQLite database — better-sqlite3 for synchronous queries, WAL mode for concurrent reads
  • Real-time WebSocket chat — server-sent events and WebSocket connections for live messaging
  • Setlist builder — drag-and-drop song management with automatic duration calculation
  • Shared calendar — event management with timezone handling
  • Member management — invite system, profile editing, role assignment
  • Full audit log — every significant action tracked with timestamps and actor info
  • Undo system — reversible operations with confirmation workflows

All of it runs on Astro in server mode with a Node.js adapter. The same .astro component files, the same layout system, the same Tailwind integration. The difference from our static sites is one line in the config: output: 'server'.

This isn’t Astro being stretched beyond its limits. It’s Astro doing exactly what it’s designed to do in server mode. Pages render on the server per-request. API routes handle mutations. Middleware handles auth checks. Components render HTML. The mental model is straightforward, and it works.

Why Astro Works for Both

The thing that makes Astro great for static sites is the same thing that makes it great for applications: it gets out of your way.

The Component Model

Astro components are server-side by default. They run at request time (SSR) or build time (static), produce HTML, and disappear. No runtime, no hydration, no client-side framework tax. When you need interactivity, you opt in with island components — drop in a React, Svelte, or vanilla JS component with client:load and only that piece ships JavaScript to the browser.

For Bandmate, most pages are server-rendered HTML with a few interactive islands. The chat panel is a client-side component. The drag-and-drop setlist editor is a client-side component. The calendar view is a client-side component. Everything else — navigation, layouts, data display, forms — is server-rendered HTML that loads instantly. Users on slow connections get a usable page immediately, with interactive features loading in after.

This is the island architecture doing real work, not just putting a contact form on a blog.

API Routes

Astro’s API routes are simple and effective. Create a .ts file in src/pages/api/, export HTTP method handlers, and you have an endpoint. No separate Express server, no serverless function configuration, no API gateway.

Bandmate’s backend is entirely Astro API routes. Authentication endpoints, CRUD operations, WebSocket upgrades, file uploads — all colocated with the pages that use them, all sharing the same TypeScript types, all deployed as a single Node.js process.

Middleware

Astro middleware runs before every request. For Bandmate, that’s where authentication checks happen. Verify the session cookie, attach the user to the request context, redirect to login if needed. Standard patterns, clean implementation.

Content Collections Still Work

Here’s the underrated part: content collections work in SSR mode too. Bandmate uses them for changelog entries and documentation. The studio site uses them for blog posts. Same Zod schemas, same type safety, same content layer. Whether the page renders at build time or request time, the content API is identical.

The Static Side Is Still Great

I don’t want the SSR story to overshadow the static capabilities, because for most websites, static is still the right call.

When Astro builds a static site, you get a folder of HTML, CSS, and assets. Drop it on any web server. No Node.js runtime in production. No cold starts, no function timeouts, no runtime errors. The site is up if Nginx is up. For content sites — and most websites on the internet are content sites — this is everything.

Our fire department site loads almost instantly because there’s nothing to load except the content. No JavaScript bundles to parse, no hydration delay. When someone needs the address of the fire hall during an emergency, page load time matters. Static Astro delivers.

The studio site you’re reading right now builds 22 pages in under five seconds. The deployment is copying files to a directory on our VPS. The maintenance burden is near zero — no databases to back up, no WordPress plugins to update, no server-side runtime to patch.

Across fourteen-plus static sites, the pattern is the same: fast builds, trivial deployments, zero ops burden. That’s hard to beat.

What I Tried Before

I’ve shipped sites with Jekyll, Hugo, Gatsby, Next.js, and plain HTML. Each had strengths, each had walls I hit.

Hugo builds faster than anything, but Go templates fight you the moment you need component logic. Reusable layouts, conditional rendering, prop passing — it all feels like working against the tool.

Gatsby introduced React components to static sites and the image pipeline was ahead of its time. But GraphQL for querying your own local files was over-engineering, and build times degraded as sites grew. The company pivoted, the community energy moved on.

Next.js is genuinely excellent — for applications that need the full React ecosystem. Server Components, sophisticated middleware chains, deep client-side state management. If your project is React to its core, Next.js is the right call. But for a fire department’s public information page, it’s a semi truck for a grocery run. And the Vercel ecosystem, while polished, nudges you toward their platform in ways that matter if you value hosting independence.

Plain HTML still works great for a single-page landing site. But shared headers across twenty pages, templated blog posts, content management — you’re reinventing the wheel.

Astro took the best ideas from all of them — component-based architecture, file-based routing, content-first defaults, framework-agnostic islands — and added a server mode that actually works. I stopped looking.

Where Astro Still Falls Short

The Ecosystem Is Younger

React has been around since 2013. Astro hit 1.0 in 2022. Fewer third-party integrations, fewer Stack Overflow answers for edge cases, fewer blog posts solving obscure problems. This is improving fast, but if you need a very specific CMS adapter or niche integration, check that it exists before committing.

Heavy SPA Territory

If your application is fundamentally a client-side single-page app — think Figma, Google Docs, complex dashboards with deeply interconnected real-time state — Astro’s server-rendered-with-islands model isn’t the right fit. You want a framework that owns the client-side runtime entirely.

Bandmate works because most of its pages are server-rendered documents with interactive islands. If the entire page needs to be a React app with shared client state, Astro’s island boundaries create friction rather than helping.

React Team Adjustment

If your team writes React all day, .astro files require a mental shift. The syntax looks similar (JSX-like), but Astro components render on the server. No state, no hooks, no lifecycle. Most React developers are productive within a day or two, but the adjustment is real.

The Deployment Story

We self-host everything on our own VPS instances behind Nginx. No Vercel, no Netlify, no serverless platforms.

Static sites: Build locally, copy the dist/ folder to the server. Nginx serves files. Done.

SSR apps: Build, deploy the Node.js process behind an Nginx reverse proxy. Systemd manages the process. Same server, same infrastructure, same workflow.

No vendor lock-in either way. No deployment abstractions. No platform-specific adapters we don’t control. The code runs on our hardware, and we can move it anywhere.

The Bottom Line

Astro is no longer “the static site framework.” It’s a web framework that defaults to simplicity and lets you scale up to full applications when you need to.

For content sites — marketing pages, blogs, portfolios, documentation, landing pages — Astro’s static mode is the best tool available. Fast builds, zero JavaScript by default, flat file output you can host anywhere.

For server-rendered applications — dashboards, portals, platforms with auth and databases — Astro’s SSR mode is surprisingly capable. Same component model, same developer experience, real server-side power.

The fact that we use the same framework for a volunteer fire department’s public information page and a collaboration platform with real-time chat and role-based permissions says something. Not every tool can span that range without becoming bloated or compromised. Astro does it by staying simple at the core and letting you add complexity only where you need it.

If you’ve been avoiding Astro because you think it’s “just for blogs” — build something real with server mode. You might be as surprised as I was.

Share this post

If this was useful, consider buying us a coffee.