Skip to content
All articles
AstroTypeScriptFrontend

Why I chose Astro for my portfolio

The decision to rebuild my portfolio in Astro, with Markdown as the source of truth and React only where there is real interactivity.

My portfolio started out in Jekyll. It worked, but every small change turned into a trip through Liquid, the Gemfile and a chain of layouts I no longer remembered by heart. I rebuilt everything in Astro. These were the reasons.

Static HTML by default

A portfolio is, in practice, a document. It doesn’t need dynamic server routes, a database or a framework that hydrates the whole page just to render text.

Astro generates static HTML by default and only ships JavaScript to the browser when a component actually needs it. On this entire site the only React component is the filter on the projects page, and even that only hydrates when it enters the viewport.

Content separate from components

What bothered me most about the old setup was having to edit a component to publish content. With Astro’s Content Collections, adding a project means creating a Markdown file:

---
title: 'My New App'
year: 2027
type: 'Aplicativo'
featured: true
status: 'production'
published: true
technologies:
  - React Native
  - TypeScript
---

The file shows up on /projects, gets its own page, lands on the home page if featured is true and goes into the sitemap. No component changes.

Schemas that prevent content mistakes

Each collection has a schema. If I write featured: "yes" instead of featured: true, the build fails with a clear message instead of silently rendering something wrong.

It’s the same reasoning as using TypeScript in the code, applied to content. The error shows up at build time, not in production.

React only where there is interactivity

Astro doesn’t force me to pick one framework for the whole site. React comes in as an island, only where there is real state. The project filter keeps the active selection, and the rest of the page remains static HTML generated at build time.

Light and dark theme, the mobile menu and the entrance animations don’t use React. They’re a few lines of JavaScript and CSS, plus a native <dialog>.

The outcome

The maintenance flow became what I wanted: I create a .md, add the images, push, and Vercel publishes it. No CMS, no backend, no step in between.

If I open this repository six months from now, adding a project will still mean creating a text file. That’s what I wanted.