Tailwind setup
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.From its SKILL.md
npx -y skills add otoshek/Claude-Code-Toolkit --skill tailwind-setupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
9.8 KB, as published. Nobody here has run it
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):
import path from 'node:path' import tailwindcss from '@tailwindcss/vite' - Update the plugins array so Tailwind runs alongside React:
plugins: [ react(), tailwindcss(), ] - Define the alias block in the same file so
@/resolves tosrc(this relies on thepathimport above):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:
@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 <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 card
npx --prefix ./frontend shadcn@latest add field
npx --prefix ./frontend shadcn@latest add input
npx --prefix ./frontend shadcn@latest add button
npx --prefix ./frontend shadcn@latest add table
npx --prefix ./frontend shadcn@latest add navigation-menu
npx --prefix ./frontend shadcn@latest add label
npx --prefix ./frontend shadcn@latest add separator
npx --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 light
if (theme === "dark") {
setTheme("light");
} else {
setTheme("dark");
}
};
return (
<Button
variant="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:
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:<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