agentsclimarketplace

Tailwind setup

Skill otoshek/Claude-Code-Toolkit/skills/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

Install
npx -y skills add otoshek/Claude-Code-Toolkit --skill tailwind-setup

Assembled 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:

  1. Install Dependencies
  2. Configure Vite for Django Backend
  3. Setup Tailwind in CSS
  4. Apply Base Theme (Required for dark mode support)
  5. Setup shadcn/ui
  6. Implement Dark Mode with Toggle
  7. 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:

  1. Read existing vite.config.js
  2. Add the required imports at the top (keep the existing React import):
    import path from 'node:path'
    import tailwindcss from '@tailwindcss/vite'
    
  3. Update the plugins array so Tailwind runs alongside React:
    plugins: [
      react(),
      tailwindcss(),
    ]
    
  4. Define the alias block in the same file so @/ resolves to src (this relies on the path import above):
    resolve: {
      alias: {
        '@': path.resolve(__dirname, './src'),
      },
    }
    

Step 3: Setup Tailwind in CSS

Configure the main CSS file to import Tailwind:

  1. Read existing src/index.css
  2. 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.

  1. 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_registries with registries=["@shadcn"] and query="card"
  • mcp__shadcn__search_items_in_registries with registries=["@shadcn"] and query="button"
  • mcp__shadcn__search_items_in_registries with registries=["@shadcn"] and query="navigation-menu"
  • mcp__shadcn__search_items_in_registries with registries=["@shadcn"] and query="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:

  1. Locate the navbar component: Find the main navigation component (commonly in src/components/Navbar.jsx or similar)
  2. Import the ThemeToggle component:
    import ThemeToggle from "@/components/ThemeToggle";
    
  3. 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.json path aliases match vite.config.js aliases
  • Confirm tailwind.config.js content 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

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.