Why Astro?

I rebuilt this portfolio site with Astro, and honestly, it’s the best decision I made for a content-heavy site. Here’s why.

The JavaScript Problem

Most modern frameworks ship tons of JavaScript to the browser. React, Vue, Next.js—they all hydrate the entire page even if you just have a static blog post. Your readers are downloading and executing JavaScript just to read text. That’s ridiculous.

Astro ships zero JavaScript by default. Your blog post is just HTML and CSS. Fast, simple, perfect.

But What About Interactivity?

Here’s where Astro gets clever. You can still use React, Vue, Svelte—whatever you want. But you choose what gets JavaScript.

See that floating action button on this site? That’s React with client:load. The rest of the page? Pure HTML.

---
import FloatingButton from '@/components/FloatingButton';
---

<FloatingButton client:load />

This is called “Islands Architecture.” Interactive components are islands in a sea of static HTML.

Content Collections Are Game-Changing

Before Astro, my blog posts were just files. No validation, no type safety, no structure.

Content Collections changed that:

const blog = defineCollection({
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    heroImage: z.string().optional(),
  }),
});

Now TypeScript knows the exact shape of every blog post. Forget to add a title? Build fails. Try to use the wrong type? Your editor yells at you.

MDX: Markdown + Components

I can write normal Markdown:

## Regular Markdown

Just writing content...

But when I need something interactive:

## Interactive Section

<InteractiveDemo />

<CodePlayground code={exampleCode} />

Components right inside Markdown. No weird workarounds.

Performance Is Insane

My Lighthouse scores:

  • Performance: 100
  • Accessibility: 100
  • Best Practices: 100
  • SEO: 100

That’s not because I’m amazing at optimization. That’s just Astro being smart about what it ships.

The Developer Experience

Astro files look like this:

---
// JavaScript goes here
const posts = await getCollection('blog');
---

<!-- HTML goes here -->
<div>
  {posts.map(post => (
    <PostCard title={post.data.title} />
  ))}
</div>

Frontmatter for logic, HTML below. Clean and intuitive.

When NOT to Use Astro

Astro isn’t for everything:

  • Dashboards with tons of interactivity? Use Next.js or Remix
  • Real-time apps? Astro isn’t built for that
  • Complex client-side routing? You’ll have a bad time

Astro is perfect for:

  • Blogs (obviously)
  • Marketing sites
  • Documentation
  • Portfolios (like this one)
  • Any content-first website

Mixing Frameworks

This is wild—you can use React AND Vue in the same project:

---
import ReactComponent from './Component.jsx';
import VueComponent from './Component.vue';
---

<ReactComponent client:load />
<VueComponent client:visible />

I don’t recommend it, but you can do it.

The Actual Getting Started

npm create astro@latest

Pick a template, install dependencies, done. The CLI is genuinely good—it asks the right questions and sets everything up correctly.

For this portfolio, I used:

  • Astro for pages and layouts
  • React for interactive UI (with client:load)
  • Tailwind for styling
  • MDX for blog posts with custom components

Real Talk

Astro isn’t perfect. The ecosystem is smaller than Next.js. Some integrations are rough around the edges. But for content-heavy sites where performance matters, nothing comes close.

If you’re building a blog, portfolio, or marketing site, try Astro. You might not go back.