← Back to Blog

Why We Choose Astro for Modern Websites

How a zero-JavaScript-by-default framework became our go-to for fast, accessible marketing sites and web applications.

Most modern web frameworks ship too much JavaScript. A marketing page that could be static HTML ends up bundled with hundreds of kilobytes of runtime code, hydration logic, and client-side routing that no visitor asked for.

When we started building limbatus.dev, we wanted the opposite: a site that loads instantly, scores perfectly on Lighthouse, and only ships JavaScript when a feature genuinely requires it.

The Problem with JavaScript-First Frameworks

React, Vue, and Svelte are excellent tools for building interactive applications. But they were designed for applications, not content. When you use them for a marketing site or blog, you inherit their entire runtime whether you need it or not.

The result is predictable:

  • A 200KB+ JavaScript bundle for a page that could be pure HTML and CSS
  • Hydration delays that block interactivity on slower devices
  • Cumulative Layout Shift from client-side rendering
  • Increased complexity for content that rarely changes

The fastest code is the code that never runs. For content-driven sites, the best JavaScript strategy is shipping none at all.

Why Astro Fits

Astro takes a different approach. Components render to HTML at build time and ship zero JavaScript by default. When you need interactivity, you opt in per-component using what Astro calls “islands” — isolated interactive regions in an otherwise static page.

This means a page like our services section is pure HTML and CSS. The scroll-triggered reveal animations? A small inline script. The mobile navigation toggle? Another small script. Everything else is static.

What we get from this architecture

  • Sub-second page loads — no framework runtime to download or parse
  • Perfect Core Web Vitals — no layout shift, no hydration delay
  • Progressive enhancement — the page works before any JavaScript loads
  • Simpler mental model — components are just HTML templates unless you explicitly make them interactive

Content Collections

Astro’s content layer is particularly well-suited for blogs and documentation. You define a schema with Zod, write your content in Markdown or MDX, and get full type safety from frontmatter through to the rendered page.

---
const posts = await getCollection('blog');
---

{posts.map((post) => (
  <article>{post.data.title}</article>
))}

No CMS integration required for simple content. No GraphQL layer. Just files in a directory with validated frontmatter.

When Astro Is Not the Right Choice

Astro is not a universal tool. If you are building a highly interactive dashboard, a real-time collaboration app, or anything that requires persistent client-side state, a full-stack framework like Next.js or SvelteKit is a better fit.

The decision framework is straightforward:

  • Mostly content, some interactivity — Astro
  • Mostly interactivity, some content — Next.js, SvelteKit, or similar
  • Pure application with no public content — React SPA, Vue SPA

The Results

This site loads in under one second on a 3G connection. It scores 100 across all four Lighthouse categories. The total JavaScript shipped to the homepage is less than 2KB — just the intersection observer for scroll animations and the mobile nav toggle.

That performance is not the result of aggressive optimization or clever tricks. It is the natural outcome of choosing a tool that does not ship code you do not need.

For our clients’ marketing sites, landing pages, and content platforms, Astro has become the default starting point. Not because it is trendy, but because it produces measurably better results for this category of work.