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.