Case Study 2026-01-15 9 min read

Building This Portfolio: Why Astro Beats React and Next.js for Static Sites

A deep dive into why I chose Astro for my portfolio website — superior performance, minimal JavaScript, excellent SEO, and a scalable data architecture using simple JavaScript files.

YM

Yosri Mlik

Software Engineer

#Astro #Static Sites #Architecture #Performance #SEO
Building This Portfolio: Why Astro Beats React and Next.js for Static Sites

When it came time to build my portfolio website, I had a choice: use the familiar React/Next.js stack I'd been working with, or try something different. After careful consideration, I chose Astro — and it was one of the best technical decisions I've made for a static site.

This isn't just another portfolio site. It's a case study in modern static site architecture, demonstrating why Astro is becoming the go-to choice for landing pages and content-heavy websites that need to be fast, SEO-friendly, and maintainable.

The Problem with Traditional Approaches

Plain HTML: No Components, No Scalability

Traditional HTML works for simple sites, but it falls apart quickly when you need:

  • Reusable components — Headers, footers, cards, and navigation elements
  • Data management — Projects, articles, and other content that changes
  • Styling consistency — CSS that doesn't become a mess
  • Modern tooling — Hot reload, optimization, and build pipelines

Next.js SSG: Overkill for Static Sites

Next.js is fantastic for dynamic applications, but for a mostly static portfolio, it brings unnecessary complexity:

  • Heavy JavaScript bundles — Even with SSG, Next.js ships React and its router
  • Complex routing — File-based routing is great, but overkill for 5-10 pages
  • Hydration overhead — React needs to hydrate on the client, adding load time
  • Build complexity — More moving parts than necessary for static content

Regular React: SEO Nightmare

A standard React SPA (Create React App, Vite, etc.) is terrible for portfolios because:

  • Poor SEO — Content rendered client-side, search engines see empty pages
  • Slow initial load — Must download React bundle before any content appears
  • No static generation — Every page is built on-demand in the browser
  • Accessibility issues — Screen readers struggle with client-rendered content

Why Astro Wins for Static Sites

Zero JavaScript by Default

Astro's killer feature is that it ships zero JavaScript by default. Components render to HTML on the server and stay as HTML in the browser unless you explicitly opt into client-side interactivity.

// This component renders to static HTML
// No JavaScript shipped to browser
---
const props = Astro.props;
---
<div class="card">
  <h2>{props.title}</h2>
  <p>{props.description}</p>
</div>

Islands Architecture

When you need interactivity, Astro's islands architecture lets you hydrate only the components that need it. Navigation menus, image sliders, or contact forms can be interactive while everything else stays static.

// Only this component gets JavaScript
<script>
  // Interactive menu logic
</script>

Superior Performance

The performance difference is dramatic:

MetricNext.js SSGAstro
Initial JS Bundle~45KB (React + Router)~0KB (static HTML)
Time to Interactive~1.2s~0.3s
Lighthouse Performance85-9095-100
SEO Score90-95100

The Architecture: Data in JavaScript Files

Why Not a CMS?

For a personal portfolio, a traditional CMS is overkill. It adds:

  • Database maintenance and backups
  • Security vulnerabilities to patch
  • Monthly hosting costs
  • Complex deployment pipelines
  • Vendor lock-in

JavaScript Files as Data Source

My solution: store data in simple JavaScript files. Here's why this scales surprisingly well:

export const projects = [
  {
    title: "AI Chat",
    technologies: ["React", "Next.js"],
    links: {
      demo: "https://...",
      repo: "https://..."
    },
    images: [
      { src: "/img/chat.png", alt: "Chat interface" }
    ]
  }
  // ... more projects
];

Technical Implementation Details

Component Architecture

The portfolio follows a clean component hierarchy:

src/
├── layouts/
│   └── Layout.astro          # Base layout with header/footer
├── components/
│   ├── Navbar.astro          # Navigation (interactive island)
│   ├── Projects/
│   │   ├── ProjectsSection.astro    # Projects listing
│   │   └── ProjectCard.astro         # Individual project card
│   └── Articles/
│       └── ArticlesSection.astro    # Article listings
├── pages/
│   ├── index.astro           # Homepage
│   └── articles/
│       ├── index.astro      # Articles listing
│       └── [slug].astro     # Individual article
└── data/
    ├── projects.js          # Project data
    └── articles.js          # Article metadata

Styling with Tailwind CSS v4

Using Tailwind v4 with CSS variables for theming:

/* CSS Variables for theme switching */
:root {
  --accent: 59, 130, 246;
  --text-primary: 31, 41, 55;
}

/* Tailwind v4 theme tokens */
@theme {
  --color-accent: rgb(var(--accent));
  --color-text-primary: rgb(var(--text-primary));
}

Performance Optimizations

  • Image optimization — Astro automatically optimizes images with width/height attributes
  • Code splitting — Only interactive components get JavaScript
  • Prefetching — Link prefetching for faster navigation
  • Critical CSS — Inline critical CSS, defer non-critical styles

SEO Advantages

Because everything renders to static HTML, search engines see perfectly structured content:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>AI Chat Project - Yosri Mlik</title>
  <meta name="description" content="Full-stack AI chatbot...">
</head>
<body>
  <h1>AI Chat</h1>
  <p>A full-stack AI chatbot that lets users...</p>
  <!-- All content visible to search engines -->
</body>
</html>

Compare this to a React SPA where search engines see:

<!DOCTYPE html>
<html>
<head><title>My Portfolio</title></head>
<body>
  <div id="root"></div>
  <script src="bundle.js"></script>
  <!-- No content for search engines! -->
</body>
</html>

Deployment Simplicity

The entire site builds to static files that can be deployed anywhere:

$ npm run build
 
dist/
├── index.html
├── projects/
│   └── index.html
├── articles/
│   ├── index.html
│   └── building-modern-ai-chatbot/
│       └── index.html
├── assets/
│   └── styles.css
└── img/
    └── chat.png

No server required, no database to maintain, no environment variables to configure. Just static files that work on any hosting platform.

When This Architecture Works Best

  • Portfolio sites — Showcase projects and articles
  • Documentation sites — Static docs with good navigation
  • Marketing landing pages — Fast loading, SEO-optimized
  • Blogs and content sites — Markdown-based content
  • Product showcases — Feature highlights and demos

When to Use Something Else

  • User-generated content — Need a database and authentication
  • Real-time features — Chat, notifications, live updates
  • Complex admin interfaces — Content management, user management
  • E-commerce — Shopping carts, payment processing

Future Scalability

This architecture scales in several ways:

Content Management

When the site grows, I can easily migrate to:

  • Headless CMS — Contentful, Sanity, or Strapi
  • Markdown files — Astro's content collections
  • Database — PostgreSQL or MongoDB with API endpoints

Performance Enhancements

  • Edge deployment — Cloudflare Workers, Vercel Edge
  • CDN integration — Global content delivery
  • Advanced caching — Service workers, browser caching

Lessons Learned

  1. Simplicity scales — Start simple, add complexity only when needed
  2. Performance matters — Fast sites rank better and convert more
  3. SEO is not optional — Even portfolios need to be discoverable
  4. Choose the right tool — Don't use React for everything

Conclusion

Building this portfolio with Astro taught me that the best architecture is often the simplest one that meets your needs. Astro's zero-JS-by-default approach, combined with static data files, creates a site that's fast, SEO-friendly, and maintainable — everything a portfolio should be.

For landing pages, portfolios, and content sites, Astro is becoming the clear choice over React and Next.js. It delivers better performance, simpler deployments, and excellent SEO without sacrificing developer experience.

Enjoyed this article?

Share it with others who might find it helpful!