Why I Chose Astro for My Personal Site

Zero JavaScript by default, posts in Markdown, and interactivity only where it matters: why I built my personal site with Astro instead of Next.js.

Published
  • #astro
  • #frontend
  • My personal site is mostly static content, so Astro ships 0 KB of JavaScript by default.
  • Markdown + content collections make writing posts fast, with frontmatter checks.
  • When you need interactivity, add an “island” where it fits, instead of pulling React into every page.

When I rebuilt my personal site, I had three goals: fast loading, easy writing, and low maintenance. Next.js is the framework I know best, but for a site that is almost all static content, it feels like overkill.

Content is at the center

Astro renders everything to HTML at build time. The browser gets a finished page and does not have to wait for hydration. For the blog, I just drop Markdown files into src/content/blog/ and a new post is live.

.md file

Content collection

astro build

Static HTML

Browser

How content collections work

The glob() loader scans files at build time, parses the frontmatter, and validates it with a Zod schema:

const blog = defineCollection({
  loader: glob({ pattern: "{vi,en}/**/*.md", base: "./src/content/blog" }),
  schema: z.object({ title: z.string(), pubDate: z.coerce.date() }),
});

Invalid data types (for example pubDate: yesterday) make the build fail right away, instead of a silent error in production. The result is cached in .astro/data-store.json, so the next build only processes changed files.

Data storeZod schemaglob() loaderData storeZod schemaglob() loaderalt[valid][invalid type]frontmatterstore entrybuild fails

Interactivity when you really need it

The reading mode switch at the top is a small script that runs only on this page. The rest of the page is still plain HTML.

Islands and the client:* directive

A framework component is hydrated only when it has a directive like client:visible or client:idle. Without a directive, it is rendered as static HTML and its JS never reaches the browser. This way, JavaScript cost grows with the number of interactive parts, not with the size of the page.

Conclusion

For a personal site, Astro gives me exactly what I need: fast by default, writing in Markdown, and added complexity only when there is a reason.

Share on Facebook
How was this post?

Drag to pan · Scroll or pinch to zoom