← Back to blog
Tutorial Tailwind CSS Astro

Building a Portfolio with Tailwind CSS and shadcn/ui

A step-by-step guide to creating a modern portfolio using Tailwind CSS, shadcn/ui components, and dark mode support.

· 2 min read

Why Tailwind CSS + shadcn/ui?

Building a portfolio from scratch can be daunting. Tailwind CSS gives you utility-first styling that’s fast to iterate on, while shadcn/ui provides beautifully designed, accessible components you can copy into your project.

The Stack

  • Astro — static site generator with island architecture
  • Tailwind CSS v4 — utility-first CSS framework
  • shadcn/ui — reusable component library
  • React — for interactive islands

Setting Up the Project

# Create a new Astro project
bun create astro@latest my-portfolio

# Add Tailwind CSS
bun add tailwindcss @tailwindcss/vite

# Add React integration
bunx astro add react

Dark Mode Implementation

One of the most requested features is dark mode. Here’s how to implement it with a toggle:

function toggleTheme() {
  const isDark = document.documentElement.classList.toggle('dark');
  localStorage.setItem('theme', isDark ? 'dark' : 'light');
}

The key is persisting the user’s preference in localStorage and applying it before the page renders to avoid flash of unstyled content (FOUC).

Responsive Design Tips

  1. Mobile-first approach — start with the smallest screen and scale up
  2. Use container queries — for component-level responsiveness
  3. Test on real devices — emulators don’t catch everything

Performance Wins

Astro’s island architecture means JavaScript is only loaded where needed. Combined with Tailwind’s purging, you get tiny bundle sizes:

  • 0 KB JS on static pages
  • < 5 KB for interactive components
  • Perfect Lighthouse scores out of the box

Conclusion

This stack gives you the best of both worlds: a fast, static site with rich interactivity where you need it. The full source code for this portfolio is available on my GitHub.