Most frameworks assume your page needs a JavaScript runtime; Astro assumes the opposite by default — ship zero JavaScript unless a specific piece of the page actually needs interactivity, then hydrate just that piece.
Astro is a web framework built for content-focused sites — blogs, marketing sites, documentation — that ships zero JavaScript by default, rendering everything to static HTML at build time. Its "islands architecture" lets you selectively hydrate individual interactive components while the rest of the page stays pure HTML, and it supports mixing components from React, Vue, Svelte, and others within the same project.
Why Astro Matters (and When to Skip It)
Content-heavy sites often ship far more JavaScript than they actually need — a blog post or marketing page with a handful of interactive widgets doesn't need a full SPA runtime hydrating the entire page. Astro's zero-JS-by-default approach directly targets this waste, resulting in dramatically better baseline performance for sites that are mostly static content with occasional interactive pieces.
Skip Astro for genuinely application-like experiences — a dashboard, a highly interactive tool, or anything where most of the page is dynamic and stateful. Astro's islands model is optimized for mostly-static content with pockets of interactivity, not for an application that's interactive throughout.
Getting Started with Astro
npm create astro@latest
cd my-app
npm run dev
An .astro component — HTML-like syntax with a frontmatter script section:
---
const posts = await fetchPosts();
---
<html>
<body>
<h1>Blog</h1>
{posts.map(post => <a href={`/blog/${post.slug}`}>{post.title}</a>)}
</body>
</html>
An interactive island, hydrated selectively using a client directive:
---
import Counter from "../components/Counter.jsx";
---
<Counter client:load />
Core Astro Concepts Every Developer Should Know
Client directives control exactly when and whether a component hydrates. client:load hydrates immediately, client:idle waits until the browser is idle, client:visible hydrates when the component scrolls into view — this granular control is the core mechanism behind shipping minimal JavaScript while still supporting rich interactivity where it's needed.
You can mix framework components within one Astro project. A React component, a Vue component, and a Svelte component can all live on the same page, each hydrated independently as its own island — useful for gradually migrating between frameworks or using the right tool for a specific interactive widget without committing the whole project to one framework.
Content Collections provide typed, validated content management for Markdown/MDX-based content (blog posts, documentation), with schema validation catching malformed frontmatter at build time rather than failing silently or at runtime.
// content/config.ts
import { defineCollection, z } from "astro:content";
const blog = defineCollection({
schema: z.object({
title: z.string(),
date: z.date(),
}),
});
Server-side rendering is available for pages that need it, alongside static generation for pages that don't — Astro supports a hybrid approach where most pages are static but specific routes render on demand.
Common Astro Mistakes and How to Fix Them
Mistake 1: over-hydrating components with client:load when a lazier directive would suffice, shipping JavaScript earlier than actually needed. Fix: use client:visible or client:idle for components that aren't immediately critical, reserving client:load for genuinely above-the-fold interactive elements.
Mistake 2: reaching for Astro on a highly interactive, application-like project where most of the page needs to be dynamic. Fix: recognize when a project is actually an application (better served by React/Vue/Svelte with their own application framework) versus content-focused (Astro's actual strength).
Mistake 3: not using Content Collections for structured Markdown content, missing out on build-time schema validation and type safety for content. Fix: define collections with schemas for any structured content, catching malformed content early rather than at runtime.
When Should You Use Astro Instead of Next.js or Nuxt.js?
Use Astro when your site is primarily content — blogs, marketing pages, documentation — with occasional interactive elements, and minimal JavaScript shipped is a priority. Use Next.js, Nuxt.js, or a similar application framework when you're building something genuinely application-like, where most of the page is interactive and stateful rather than mostly static content.
Astro in Production
Be deliberate about client directives on every interactive component — the default temptation to reach for client:load everywhere undermines Astro's core value proposition. Also periodically audit shipped JavaScript (via a build analysis) to confirm you're actually getting the minimal-JS benefit Astro is meant to provide, since it's easy to erode that advantage gradually as a project grows.
If your current site ships a full framework runtime for content that's genuinely mostly static, that's exactly the case Astro is built to fix — worth evaluating for a content-heavy site or marketing pages specifically.