Skill v1.0.1
currentAutomated scan100/1001 files
version: "1.0.1" name: tailwind-setup description: Configure Tailwind CSS and shadcn/ui for React frontends with Django backends, including dark mode support and theme tokens. This skill should be used when setting up a new React project or adding Tailwind to an existing one. allowed-tools: Bash, Write, Edit, Read, Glob, Grep, TodoWrite, mcp__shadcn__get_project_registries, mcp__shadcn__search_items_in_registries, mcp__shadcn__view_items_in_registries, mcp__shadcn__get_item_examples_from_registries, mcp__shadcn__get_add_command_for_items, mcp__shadcn__get_audit_checklist
Purpose
Configure Tailwind CSS with shadcn/ui for React frontends connecting to Django backends. This setup includes dark mode support, theme tokens, and shadcn/ui component integration. The configuration enables automatic dark mode switching and provides a foundation for building consistent, themeable user interfaces.
Setup Process Overview
Follow these steps in order:
- Install Dependencies
- Configure Vite for Django Backend
- Setup Tailwind in CSS
- Apply Base Theme (Required for dark mode support)
- Setup shadcn/ui
- Implement Dark Mode with Toggle
- Verify Setup and Check for Errors
Step 1: Install Dependencies
Install Tailwind CSS and the Vite plugin:
npm --prefix ./frontend tailwindcss @tailwindcss/vite
Step 2: Configure Vite for Django Backend
Configure vite.config.js to enable Tailwind and path aliases:
- Read existing
vite.config.js - Add the required imports at the top (keep the existing React import):
``javascript import path from 'node:path' import tailwindcss from '@tailwindcss/vite' ``
- Update the plugins array so Tailwind runs alongside React:
``javascript plugins: [ react(), tailwindcss(), ] ``
- Define the alias block in the same file so
@/resolves tosrc(this relies on thepathimport above):
``javascript resolve: { alias: { '@': path.resolve(__dirname, './src'), }, } ``
Step 3: Setup Tailwind in CSS
Configure the main CSS file to import Tailwind:
- Read existing
src/index.css - Replace the entire contents with the Tailwind import:
``css @import "tailwindcss"; ``
Step 4: Apply Base Theme
Apply the base theme by running the bundled script from the project root directory at: scripts/apply-theme.sh
Apply the base theme by running the script from the skill's bundled resources at:scripts/apply-theme.sh within this skill's directory.
The script requires requires the frontend directory path (relative to project root) as an argument.
- Run the theme script from project root:
``bash bash <path-to-skill>/scripts/apply-theme.sh frontend ``
The script appends shadcn/ui's design tokens (from assets/tailwind-theme.css, in the skill's bundled resources) to src/index.css, adding support for typography, colors, and automatic dark mode.
Step 5: Setup shadcn/ui
5a. Install shadcn/ui Dependencies
Install the required packages for shadcn/ui component functionality:
npm --prefix ./frontend install class-variance-authority clsx tailwind-merge lucide-react
5b. Create jsconfig.json for Path Aliases
Create jsconfig.json in the frontend root directory:
{"compilerOptions": {"baseUrl": ".","paths": {"@/*": ["./src/*"]}}}
5c. Create Utility Helper Function
Create src/lib/utils.js:
import { clsx } from "clsx"import { twMerge } from "tailwind-merge"export function cn(...inputs) {return twMerge(clsx(inputs))}
5d. Create components.json Configuration
Create components.json in the frontend root directory:
{"$schema": "https://ui.shadcn.com/schema.json","style": "new-york","rsc": false,"tsx": false,"tailwind": {"config": "tailwind.config.js","css": "src/index.css","baseColor": "neutral","cssVariables": true,"prefix": ""},"aliases": {"components": "@/components","utils": "@/lib/utils","ui": "@/components/ui","lib": "@/lib","hooks": "@/hooks"}}
5e. Install shadcn/ui Components
PREREQUISITE: Before installing components, verify their availability and review usage patterns using the shadcn MCP server. This ensures compatibility with the current registry and helps understand proper implementation patterns.
MCP Verification:
Use the shadcn MCP tools to search for each component and confirm it exists in the registry:
mcp__shadcn__search_items_in_registrieswithregistries=["@shadcn"]andquery="card"mcp__shadcn__search_items_in_registrieswithregistries=["@shadcn"]andquery="button"mcp__shadcn__search_items_in_registrieswithregistries=["@shadcn"]andquery="navigation-menu"mcp__shadcn__search_items_in_registrieswithregistries=["@shadcn"]andquery="alert"
Install Required Components:
Once verified, install the components using the shadcn CLI:
npx --prefix ./frontend shadcn@latest add cardnpx --prefix ./frontend shadcn@latest add fieldnpx --prefix ./frontend shadcn@latest add inputnpx --prefix ./frontend shadcn@latest add buttonnpx --prefix ./frontend shadcn@latest add tablenpx --prefix ./frontend shadcn@latest add navigation-menunpx --prefix ./frontend shadcn@latest add labelnpx --prefix ./frontend shadcn@latest add separatornpx --prefix ./frontend shadcn@latest add alert
Step 6: Implement Dark Mode with Toggle
6a. Configure Tailwind for Class-based Dark Mode
Create or update tailwind.config.js in the frontend root directory, to enable class-based dark mode:
/** @type {import('tailwindcss').Config} */export default {darkMode: 'class',content: ["./index.html","./src/**/*.{js,jsx}",],}
6b. Create Theme Context
Create src/contexts/ThemeContext.jsx:
import { createContext, useContext, useEffect, useState } from "react";const ThemeContext = createContext({theme: "system",setTheme: () => null,});export function ThemeProvider({ children, defaultTheme = "system", storageKey = "theme" }) {const [theme, setTheme] = useState(() => {return localStorage.getItem(storageKey) || defaultTheme;});useEffect(() => {const root = document.documentElement;root.classList.remove("dark");if (theme === "system") {const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches;if (systemTheme) {root.classList.add("dark");}return;}if (theme === "dark") {root.classList.add("dark");}}, [theme]);const value = {theme,setTheme: (newTheme) => {localStorage.setItem(storageKey, newTheme);setTheme(newTheme);},};return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;}export function useTheme() {const context = useContext(ThemeContext);if (context === undefined) {throw new Error("useTheme must be used within a ThemeProvider");}return context;}
6c. Create Theme Toggle Button Component
Create src/components/ThemeToggle.jsx:
import { Moon, Sun } from "lucide-react";import { Button } from "@/components/ui/button";import { useTheme } from "@/contexts/ThemeContext";export default function ThemeToggle() {const { theme, setTheme } = useTheme();const toggleTheme = () => {// If currently system or light, switch to dark// If currently dark, switch to lightif (theme === "dark") {setTheme("light");} else {setTheme("dark");}};return (<Buttonvariant="ghost"size="icon"onClick={toggleTheme}aria-label="Toggle theme"className="cursor-pointer"><Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" /><Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" /></Button>);}
6d. Wrap App with ThemeProvider
Update src/App.jsx to include the ThemeProvider:
import Router from "./router";import { ThemeProvider } from "@/contexts/ThemeContext";function App() {return (<ThemeProvider defaultTheme="system" storageKey="theme"><Router /></ThemeProvider>);}export default App;
6e. Add Theme Toggle to Navbar
Integrate the ThemeToggle component into the navigation bar:
- Locate the navbar component: Find the main navigation component (commonly in
src/components/Navbar.jsxor similar) - Import the ThemeToggle component:
``js import ThemeToggle from "@/components/ThemeToggle"; ``
- Add the toggle to the navbar: Place the
<ThemeToggle />component in an appropriate location within the navbar, typically in the right section alongside other navigation items:
``jsx <nav className="flex items-center justify-between p-4"> <div>{/* Logo and left-side nav items */}</div> <div className="flex items-center gap-4"> {/* Other right-side nav items */} <ThemeToggle /> </div> </nav> ``
Step 7: Run Build to Check for Compilation Errors
Build the project to verify there are no compilation errors:
npm --prefix ./frontend run build
If the build succeeds, the setup is complete. If there are errors:
- Check for missing imports or incorrect file paths
- Verify all components were installed correctly
- Ensure
jsconfig.jsonpath aliases matchvite.config.jsaliases - Confirm
tailwind.config.jscontent paths include all component files
Setup Complete
The Tailwind CSS and shadcn/ui setup is now complete. The project includes:
- Tailwind CSS with Vite integration
- shadcn/ui design tokens and theme variables
- Dark mode support with class-based switching
- Path aliases configured for clean imports (
@/components,@/lib, etc.) - Core shadcn/ui components installed and ready to use