Jean Galea

AI, Investing, Health, and Building Businesses

  • Start Here
  • AI & Tech
    • AI
    • Tech
    • Modern Web Stack
    • Business
  • Investing
    • Investing Basics
    • Crypto
    • Stocks
    • P2P Lending
    • Real Estate
    • Calculators
    • Dividends
    • FIRE & Early Retirement
    • European Investing Hub
  • Life
    • Essays
    • Barcelona
    • Padel
    • Health & Fitness
    • Hobbies
    • Family
  • About
    • My Story
    • Projects
    • AI Consultancy
    • Plugins
    • Speaking
  • Blog
  • Community
    • Good Life Collective
    • Daily Driver AI
  • Search

Tailwind, shadcn/ui, and the New Design-System Meta

Last updated: October 31, 2026Leave a Comment

The shadcn/ui homepage showing a grid of sample interface components

This is part of a series on the modern web stack, written from a WordPress developer’s seat for people who’ve built on the web for years and still hit stack terms they can’t define. The goal is literacy, enough that you can read any stack list and know what each piece does.

Each post has a 10-15 minute audio companion, generated with NotebookLM, for the gym or the commute.

For most of my WordPress career, styling meant a style.css in the theme directory, maybe split into partials, possibly compiled from SCSS, with Genesis or Underscores underneath. Classes had semantic names like .site-header, .entry-content and .widget-area. You named elements by role, styled each one in a stylesheet and hoped you remembered which class belonged where.

Then I opened a modern Next.js codebase and every HTML element looked like this:

<div className="flex items-center justify-between rounded-lg border bg-card px-4 py-3 text-sm shadow-sm">

No semantic class names, no external stylesheet, just a wall of short utility classes inside the markup. My first reaction was somewhere between confusion and revulsion. I assumed this was what people meant when they said modern frontend was a mess.

I was wrong. Tailwind has won, for reasons that take a while to see from the outside. On top of it sits shadcn/ui, which does something stranger and more effective still. This post explains both.

Tailwind CSS

Tailwind is a utility-first CSS framework. Instead of class names that describe what an element is (button-primary, nav-item), you write class names that describe what it does (px-4 py-2 bg-blue-500 rounded text-white). The advantages take a minute to surface.

You stop naming things

Every WordPress theme developer has burned hours choosing between .cta, .action, .primary-button, .button-primary and .btn-cta. With Tailwind the question never comes up, because you compose the styles directly.

The stylesheet stops growing

Traditional CSS files balloon as features are added, with old rules left in case something still uses them. Tailwind’s stylesheet stays about the same size at ten components or ten thousand, since every class gets reused. The build also strips unused classes, so production CSS is tiny.

The design tokens enforce consistency

You define the color palette, spacing scale, type scale and breakpoints once, and every utility class draws from those tokens. Designers and developers can’t drift from the system because the framework won’t let them.

Components stay self-contained

A Tailwind component is fully described by its own JSX. You can read its appearance from the markup, without opening a stylesheet to find out what .entry-meta does in this particular theme.

The cost is busy markup. That’s an acceptable price in component-based development, where you read one component at a time instead of the whole site.

shadcn/ui

shadcn/ui builds on Tailwind to solve the component primitives problem.

Most design systems shipped as packages you installed: Material UI, Chakra, Ant Design. You imported their components, customized them through props and lived with their API indefinitely. Customization always hit a ceiling, and the bundle always grew.

shadcn/ui isn’t a package. It’s a CLI that copies component source code into your repo. Run npx shadcn add button and a Button component appears in src/components/ui/button.tsx. Edit it however you like. There’s no library to update, because the code is yours.

The components sit on Radix UI, an accessible primitive library, and are styled with Tailwind. They look good by default, follow accessibility practice and become customizable by editing the code. That combination has taken over the React component-library market faster than almost anything in the last three years.

The WordPress Analogue

Tailwind is to CSS what Gutenberg’s block library is to page-builder shortcodes: opinionated primitives that compose into anything. shadcn/ui is to React components what a starter theme is to a custom WordPress theme: a working template you customize instead of a library you call.

WordPress had this debate fifteen years ago. Write semantic CSS classes and let the stylesheet describe the design, or use utility classes the way Bootstrap did and compose inline? WordPress culture chose semantic and React culture chose utility. The React choice happened to fit component-based development in a way that Bootstrap on top of WP themes never did.

The Styling Approaches You’ll Meet

These are the main approaches in modern React projects:

Approach Style location Strengths Trade-offs
Tailwind CSS Inline className utilities Tiny CSS bundle, consistency, no naming Verbose markup, learning curve
CSS Modules Co-located CSS files scoped to the component Familiar CSS syntax, automatic scoping More files, harder to share design tokens
CSS-in-JS (styled-components, Emotion) Inside JS files Dynamic styling, theme support Runtime overhead, increasingly unpopular
Vanilla CSS Old-school stylesheets No build complexity, simplest model Drift, hard to scale on teams
Tailwind + shadcn/ui Tailwind utilities + copy-in components The default modern setup, ships fast Tailwind verbosity carries through
Component libraries (Material UI, Chakra) Library-provided components, theme system A complete design system fast Customization hits walls, larger bundles

In 2026, Tailwind plus shadcn/ui is the default for almost any new React or Next.js project. A starter kit usually means Next.js, Tailwind, shadcn/ui and maybe Drizzle and Supabase.

Tailwind 4, which shipped in early 2025, dropped the JavaScript config file and reads design tokens from CSS itself. Older guides reference tailwind.config.js, while the current setup is more CSS-native.

What This Changes for WordPress People

Custom Gutenberg blocks get easier

The block editor is built on React, and Tailwind works inside Gutenberg blocks. If you’ve shipped a custom block with bespoke CSS, switching to Tailwind cuts the styling work a lot, and the blocks look more at home on the modern web.

Design hand-offs improve

When a designer hands you a Figma file with spacing tokens (4, 8, 12, 16, 24) and a color palette, you map them straight into Tailwind’s config and the system stays intact through the build. WordPress themes tend to drift from designs because the developer invents its own classes.

AI agents write better styles

Agents are good at Tailwind because the class names are short, the patterns are well documented and the constraints stop them from inventing styles. Give an agent a Figma file and ask for Tailwind plus shadcn/ui, and the output is usually about 90% right. The same agent writing WordPress theme CSS produces inconsistent, hard-to-review results.

Where Tailwind Gets Messy

Verbosity

A complex component can have classes that wrap to three lines. Use the @apply directive for patterns you reuse across the site, such as a button style, but don’t abstract every component into a custom class. The verbosity is the price of the consistency and the small bundle.

Dark mode needs setup

Tailwind has a dark: variant you can apply to any class. For dark mode to work end to end you also need a palette designed for both modes and a toggle that adds and removes the dark class on the root element. The mechanism is simple and the design work isn’t.

shadcn/ui components are your code

Updates don’t arrive through pnpm update. To get a newer version of a component, you re-run the CLI command and accept the new copy. That’s the cost of having the code in your repo, so track which components you’ve copied and when.

Mixed styling approaches

A codebase that’s half Tailwind, half CSS Modules and half styled-components turns incoherent fast. Pick one approach per project.

The first two weeks

New developers see a Tailwind component and recoil. After two weeks of writing it, the markup reads normally and the trade-off makes sense. Give it those two weeks before deciding.

From Recognizing Tailwind to Using It

A few resources if you want to go from recognizing Tailwind to writing it productively.

Video

  • “Tailwind CSS in 100 Seconds” by Fireship, then “Why I use Tailwind for everything” by Theo (about 20 minutes).
  • The shadcn/ui tutorial on the shadcn channel (about 30 minutes). The CLI workflow is unusual enough that watching it once beats reading about it.

Docs worth bookmarking

  • The Tailwind CSS docs. The utility-first introduction is the best argument for the approach, so read it before deciding you hate Tailwind.
  • The shadcn/ui docs. Browse the component gallery and you’ll recognize the design language from half the modern web.
  • The Radix UI primitives that shadcn/ui is built on, useful if you ever build custom interactive components.

For which copy-paste component libraries and AI-coder tooling feed shadcn into your build, see the companion piece Why AI-Generated UI Looks Generic (and How to Fix It).

The next post ties WordPress back into the modern stack with headless WordPress: what it is, when it makes sense and how to think about hybrid CMS-plus-modern-frontend projects.

Related

Four near-identical AI-generated SaaS dashboards
Why AI-Generated UI Looks Generic (and How to Fix It)
A Comprehensive Guide to Malta’s 5% Effective Corporate Tax Rate
LinkedIn operating system: treat your profile like a landing page, then post with a system
Treat LinkedIn Like a Landing Page: My Full System
I Own Two Mazdas. The New CX-5 Is Why I Won’t Buy a Third.
Building a NAS Backup System (With Extras)
Getting an Online Extranjeria Appointment in Spain

Filed under: Modern Web Stack for WordPress Developers

Part 14 of 16 · Modern Web Stack for WordPress Developers

← PreviousObservability When You Can’t Just SSH InNext →Headless WordPress: The Bridge
All 16 modules
  1. Why Modern Web Feels Alien to WordPress Devs
  2. JavaScript and TypeScript for PHP People
  3. React, in WordPress Terms
  4. Next.js: The WordPress of React
  5. When NOT to Use Next.js
  6. Beyond Shared MySQL: Cloud Databases for WordPress Developers
  7. From WPDB to Drizzle, Prisma, and Kysely
  8. Auth in 2026: What Replaced wp_users
  9. Hosting Beyond Kinsta: Vercel, Fly, Railway, Cloudflare, and Friends
  10. Serverless and Edge Functions, Finally Explained
  11. Docker for WordPress Developers
  12. CI/CD: Goodbye FTP, Hello GitHub Actions
  13. Observability When You Can't Just SSH In
  14. Tailwind, shadcn/ui, and the New Design-System Meta
  15. Headless WordPress: The Bridge
  16. How the Pieces Wire Up: A Modern Stack Integration Tour

About Jean Galea

I build things on the internet and write about AI, investing, health, and how to live well. Founder of AgentVania and the Good Life Collective.

Leave a Reply Cancel reply

Thanks for choosing to leave a comment. Please keep in mind that all comments are moderated according to our comment policy, and your email address will NOT be published. Please Do NOT use keywords or links in the name field.

Jean Galea

Founder | AI builder | Dad of three | Athlete

Follow @jeangalea

  • My Padel Journey
  • Affiliate Disclaimer
  • Cookies
  • Contact

Copyright © 2006 - 2026