Skip to main content
All articles
Tutorial April 15, 2026 8 min read

React 19 + Tailwind CSS v4: The Complete Setup Guide

Everything you need to set up React 19 with Tailwind CSS v4 — from project creation to theming, dark mode, and your first component. No config files needed.

By Ninna UI Team


React 19 and Tailwind CSS v4 are a powerful combination — React's latest features meet Tailwind's CSS-first rewrite. This guide walks through a complete setup from scratch, including theming, dark mode, and your first accessible component.

1. Create a Vite + React 19 project

npm create vite@latest my-app -- --template react-ts
cd my-app && npm install

2. Install Tailwind CSS v4

Tailwind v4 uses a Vite plugin instead of PostCSS. Install the plugin and the CLI:

npm install tailwindcss @tailwindcss/vite

Add the plugin to your Vite config:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
});

3. Set up CSS (no config file)

Tailwind v4 is CSS-first. There is no tailwind.config.ts. Replace your src/index.css with:

@import "tailwindcss";

/* Dark mode variant */
@variant dark (&:is(.dark *));

That's it for Tailwind. No config file, no content paths, no theme object. Everything is CSS.

4. Add a component library (optional)

Install Ninna UI for 69 accessible, themed components:

npm install @ninna-ui/core @ninna-ui/primitives @ninna-ui/forms @ninna-ui/layout

Add a theme preset to your CSS:

@import "tailwindcss";
@import "@ninna-ui/core/theme/presets/default.css";
@variant dark (&:is(.dark *));

5. Dark mode toggle

With CSS-first theming, dark mode is just a class toggle:

document.documentElement.classList.toggle("dark");

No provider, no context, no re-render. The browser handles the theme switch through CSS.

6. Your first component

import { Button, Heading, Input } from "@ninna-ui/primitives";
import { Field } from "@ninna-ui/forms";
import { VStack } from "@ninna-ui/layout";

export function NewsletterForm() {
  return (
    <VStack gap="4" as="form">
      <Heading as="h1" size="2xl">Subscribe</Heading>
      <Field label="Email">
        <Input type="email" placeholder="you@example.com" />
      </Field>
      <Button type="submit" color="primary">Subscribe</Button>
    </VStack>
  );
}

Wrapping up

You now have a React 19 + Tailwind CSS v4 project with accessible components, oklch theming, and dark mode — all without a single config file. The CSS-first approach means your build is faster, your bundle is smaller, and your theming is more maintainable.


Build it with Ninna UI

Accessible React components, CSS-only theming, Tailwind v4 native.

Get Started

Keep reading