Using Tailwind in VitePress

When building my personal site with VitePress, I wanted to leverage the power and flexibility of Tailwind CSS for styling. While VitePress comes with excellent default theming, integrating Tailwind opens up a world of utility-first styling possibilities. Here's how I successfully integrated Tailwind CSS v4 into my VitePress project.

Why Tailwind CSS with VitePress? ​

VitePress is fantastic for documentation and content-driven sites, but sometimes you need more granular control over styling. Tailwind CSS provides:

  • Utility-first approach: Rapid prototyping and consistent spacing
  • Custom design system: Easy integration with existing CSS variables
  • Typography plugin: Enhanced markdown styling with @tailwindcss/typography
  • Modern workflow: Perfect complement to VitePress's Vite-powered build system

The Integration Process ​

Step 1: Installing Dependencies ​

I used Tailwind CSS v4 with the new Vite plugin approach:

bash
npm install -D tailwindcss @tailwindcss/vite @tailwindcss/typography

This modern approach eliminates the need for PostCSS configuration and provides better Vite integration.

Step 2: VitePress Configuration ​

The key was configuring VitePress to use Tailwind's Vite plugin in .vitepress/config.mts:

typescript
import { defineConfig, UserConfig } from "vitepress";
import tailwindcss from "@tailwindcss/vite";

const config: UserConfig = {
  // ... other config
  vite: {
    plugins: [tailwindcss()],
  },
  // ... rest of config
};

This integration feels much cleaner than traditional PostCSS setups.

Step 3: CSS Architecture ​

Instead of the traditional @tailwind directives, Tailwind v4 uses a more modern import syntax in .vitepress/theme/custom.css:

css
@import url("https://api.fontshare.com/v2/css?f[]=general-sans@400,600,700&f[]=azeret-mono@400&display=swap");
@import "tailwindcss" source(".");
@plugin "@tailwindcss/typography";

:root {
  --font-sans: "General Sans", sans-serif;
  --font-mono: "Azeret Mono", monospace;
}

The source(".") parameter is crucial - it tells Tailwind to scan the current directory and subdirectories for utility classes. Without this, Tailwind wouldn't detect your classes in Vue components.

Benefits of This Approach ​

Enhanced Typography ​

The @tailwindcss/typography plugin provides beautiful default styling for markdown content:

css
.prose {
  --tw-prose-headings: var(--foreground-color);
  --tw-prose-body: var(--foreground-color);
}

Design System Integration ​

Tailwind v4's CSS variable support integrates seamlessly with my existing design tokens:

css
:root {
  --font-sans: "General Sans", sans-serif;
  --font-mono: "Azeret Mono", monospace;
}

Modern Build Process ​

Using the Vite plugin eliminates build configuration complexity and provides:

  • Hot module replacement for CSS changes
  • Optimal build output with automatic purging
  • Better debugging experience in development

Challenges and Solutions ​

Challenge: Maintaining VitePress Functionality ​

Solution: Keep the custom layout system minimal and leverage VitePress's built-in content processing.

Challenge: Managing Tailwind's CSS Reset ​

Solution: Tailwind's preflight will normalize all default browser styles, which can affect VitePress's built-in components. Use @layer directives and CSS custom properties to maintain compatibility with VitePress theming.

Challenge: Performance Optimization ​

Solution: Tailwind v4's improved tree-shaking ensures only used utilities are included in the final bundle.

Final Thoughts ​

Integrating Tailwind CSS v4 with VitePress using the modern Vite plugin approach provides the best of both worlds: VitePress's excellent content handling and Tailwind's powerful utility system. The result is a flexible, maintainable, and performant setup that scales well for content-driven sites.

This integration approach feels particularly well-suited for developers who want to maintain full control over their design system while leveraging VitePress's excellent developer experience for content management.