Construindo Sites Performáticos com Astro e Tailwind CSS v4
Aprenda a combinar Astro com Tailwind CSS v4 para criar sites estáticos ultra-rápidos, com design tokens via @theme e zero JavaScript desnecessário.
Por que Astro + Tailwind CSS v4
Astro foi criado com uma premissa simples: envie menos JavaScript. Combinado com o Tailwind CSS v4, que abandona o arquivo de configuração JS em favor de CSS nativo via @theme, você tem uma stack que resulta em sites com Lighthouse 100 sem esforço.
Este portfólio que você está lendo foi construído com essa combinação.
Configurando o projeto
O setup com Astro 5 e Tailwind v4 é direto:
npm create astro@latest meu-site
cd meu-site
npm install tailwindcss @tailwindcss/vite
No astro.config.mjs, adicione o plugin Vite:
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});
Design tokens com @theme
A grande novidade do Tailwind v4 é definir tokens diretamente no CSS:
@import "tailwindcss";
@theme {
--color-brand: #0078D4;
--color-brand-hover: #006CBE;
--color-surface-primary: #FFFFFF;
--color-foreground-primary: #1A1D26;
--font-sans: "Inter", system-ui, sans-serif;
}
Esses tokens se tornam classes utilitárias automaticamente: bg-brand, text-foreground-primary, font-sans. Sem tailwind.config.js.
Dark mode com CSS custom properties
O dark mode funciona sobrescrevendo as custom properties:
html.dark {
--color-brand: #4BA0E8;
--color-surface-primary: #0a0a0b;
--color-foreground-primary: #f0f0f0;
}
Com um toggle em JavaScript que adiciona/remove a classe dark no <html> e salva no localStorage, você tem dark mode completo sem framework de estado.
Componentes Astro: zero JS por padrão
Componentes .astro são renderizados no build e enviam HTML puro. Use <script> apenas quando precisar de interatividade:
---
const { title } = Astro.props;
---
<section>
<h2>{title}</h2>
<slot />
</section>
Nenhum JavaScript é enviado ao cliente por esse componente. Compare com React, onde até um <div> estático carrega o runtime.
Classes utilitárias reutilizáveis
Crie classes no @layer components para padrões repetidos:
@layer components {
.btn-primary {
@apply inline-flex items-center gap-2 rounded-full
bg-brand px-7 py-3.5 text-sm font-semibold
text-white transition-all hover:bg-brand-hover;
}
.card {
@apply rounded-2xl border border-stroke-subtle
bg-surface-primary p-6 transition-all
hover:border-brand/20 hover:shadow-xl;
}
}
Content Collections para o blog
Astro oferece Content Collections com schema Zod para posts tipados:
const blog = defineCollection({
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
tags: z.array(z.string()).default([]),
lang: z.enum(["pt", "en"]).default("pt"),
}),
});
Cada post Markdown é validado no build. Erros de tipagem são capturados antes do deploy.
Performance real
Este portfólio, com 20+ páginas, 16 posts de blog, i18n bilíngue e dark mode:
- Build time: ~1 segundo
- JavaScript enviado: Apenas para interações (theme toggle, filtros, menu mobile)
- Lighthouse: 100/100 em Performance, Accessibility, Best Practices e SEO
- First Contentful Paint: < 0.5s
Quando NÃO usar Astro
Astro não é a resposta para tudo. Se você precisa de:
- Aplicação com estado complexo (dashboard com muita interatividade): Use Next.js ou Remix
- Aplicação em tempo real (chat, colaboração): Use Next.js com WebSockets
- SPA com transições ricas: Use React Router ou similar
Astro brilha em sites orientados a conteúdo: portfólios, blogs, documentação, landing pages e sites institucionais.
Conclusão
A combinação Astro + Tailwind CSS v4 entrega a melhor experiência possível para sites estáticos em 2026. CSS nativo para design tokens, zero JavaScript por padrão, e Content Collections tipadas fazem dessa stack a escolha ideal para desenvolvedores que valorizam performance e DX.