Most frameworks ship 200KB+ of JavaScript to show a blog post. Astro ships zero JS by default. And Astro 5's Content Layer makes content management effortless.
What is Astro?
Astro is a web framework for building content-driven websites — blogs, docs, marketing sites, portfolios. It renders HTML on the server and ships zero JavaScript unless you explicitly add it.
What's New in Astro 5
1. Content Layer API
// src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/data/blog' }),
schema: z.object({
title: z.string(),
date: z.date(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
Type-safe content from any source — Markdown, CMS, API, database.
2. Server Islands
---
// Static page shell — cached at edge
---
<html>
<body>
<Header />
<main>{staticContent}</main>
<!-- Dynamic island — rendered on server per request -->
<UserProfile server:defer>
<LoadingSpinner slot="fallback" />
</UserProfile>
<Footer />
</body>
</html>
Static shell loads instantly. Dynamic parts stream in from the server.
3. Zero JS by Default
---
// This component ships ZERO JavaScript to the browser
const posts = await getCollection('blog');
---
<ul>
{posts.map(post => (
<li>
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
<time>{post.data.date.toLocaleDateString()}</time>
</li>
))}
</ul>
4. Use Any UI Framework
---
import ReactCounter from '../components/Counter.jsx';
import VueHeader from '../components/Header.vue';
import SvelteWidget from '../components/Widget.svelte';
---
<VueHeader />
<main>
<ReactCounter client:visible />
<SvelteWidget client:idle />
</main>
Mix React, Vue, Svelte, Solid, Preact, Lit — in the same page.
5. Client Directives
<!-- No JS shipped -->
<StaticComponent />
<!-- JS loads when component enters viewport -->
<InteractiveChart client:visible />
<!-- JS loads when browser is idle -->
<Analytics client:idle />
<!-- JS loads immediately -->
<CriticalWidget client:load />
<!-- JS loads on specific media query -->
<MobileMenu client:media="(max-width: 768px)" />
6. Built-in View Transitions
---
import { ViewTransitions } from 'astro:transitions';
---
<html>
<head>
<ViewTransitions />
</head>
<body>
<main transition:animate="slide">
<slot />
</main>
</body>
</html>
Performance
| Metric | Astro | Next.js | Gatsby |
|---|---|---|---|
| JS shipped (blog) | 0 KB | 80+ KB | 100+ KB |
| Build time (1K pages) | 8s | 25s | 45s |
| Lighthouse score | 100 | 85-95 | 80-90 |
Astro vs Next.js vs Gatsby
| Astro | Next.js | Gatsby | |
|---|---|---|---|
| Best for | Content sites | Web apps | Content sites |
| Default JS | Zero | React runtime | React + GraphQL |
| UI frameworks | Any | React only | React only |
| Content | Content Layer | MDX/custom | GraphQL |
| SSR | Optional | Default | Via DSG |
Getting Started
npm create astro@latest
The Bottom Line
Astro 5 is the fastest way to build content websites. Zero JS by default, any UI framework, type-safe content, and server islands. If your site is content-driven, nothing beats Astro.
Need data tools? I build web scraping solutions. Check my Apify actors or email spinov001@gmail.com.
Top comments (0)