A complete step-by-step guide to quickly set up **React + Vite + Tailwind CSS + Shadcn UI* with clean @/... alias imports β no TypeScript required!*
β±οΈ Time to complete: ~10 minutes
π― Result: Production-ready React app with beautiful, accessible components
π§© Step 1: Create a Vite + React Project
Scaffold your new project with Vite:
npm create vite@latest my-app
cd my-app
When prompted, select:
Option | Choice
Framework | React
Variant | JavaScript
β Vite will generate a lean, fast React starter with HMR (Hot Module Replacement) out of the box.
π Step 2: Install Dependencies
Install core packages and Tailwind's official Vite plugin:
npm install
npm install tailwindcss @tailwindcss/vite
| Package | Purpose |
|---|---|
tailwindcss |
Utility-first CSS framework |
@tailwindcss/vite |
First-party Vite plugin for Tailwind (no PostCSS config needed!) |
π¨ Step 3: Configure vite.config.js
Replace the entire contents of vite.config.js with:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import path from "path";
// https://vite.dev/config/
export default defineConfig({
plugins: [
tailwindcss(),
react({
babel: {
plugins: [["babel-plugin-react-compiler"]], // β
Optional: React Compiler for perf
},
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"), // β
Enable @/ imports
},
},
});
π Why This Matters:
-
@tailwindcss/viteβ Compiles Tailwind at build time (faster than PostCSS!) -
@alias β Import likeimport Button from "@/components/ui/button"instead of../../../components/ui/buttonπ§Ή
βοΈ Step 4: Create jsconfig.json for Editor Support
At your project root, create jsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
π‘ Benefits:
- β
VS Code autocomplete for
@/imports - β ESLint/Prettier understand your alias paths
- β No more "Cannot find module" warnings π»
πͺ Step 5: Import Tailwind in Your CSS
Open or create src/index.css and add:
@import "tailwindcss";
π That's it! With
@tailwindcss/vite, you don't need@tailwind base/components/utilitiesβ the plugin handles it automatically.
(Optional) Clean up default styles:
Delete or empty src/App.css to avoid conflicting styles.
π Step 6: Initialize Shadcn UI
Run the Shadcn CLI to set up your component library:
npx shadcn@latest init
Follow the prompts:
| Question | Recommended Choice |
|----------|-------------------|
| Style | New York or Default |
| Base color | Slate (neutral & accessible) |
| CSS variables | Yes (for theming) |
Then add your first components:
npx shadcn@latest add button card input
β
Components land in src/components/ui/ β fully customizable, accessible, and Tailwind-powered.
π» Step 7: Test Your Setup
Open src/App.jsx and replace with:
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
export default function App() {
return (
<div className="flex min-h-screen items-center justify-center bg-gray-50 p-4">
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle className="text-center">π Setup Successful!</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<p className="text-center text-gray-600">
You're now running React + Vite + Tailwind + Shadcn UI.
</p>
<Button className="w-full">Click Me</Button>
<Button variant="outline" className="w-full">
Secondary Action
</Button>
</CardContent>
</Card>
</div>
);
}
Then start the dev server:
npm run dev
π Visit http://localhost:5173 β you should see a beautifully styled card with Shadcn buttons!
β Final Project Structure
my-app/
βββ public/
βββ src/
β βββ components/
β β βββ ui/ # π¨ Shadcn components (button, card, input...)
β βββ App.jsx # π Main app component
β βββ index.css # π¨ Tailwind import
β βββ main.jsx # β‘ React entry point
βββ index.html
βββ vite.config.js # βοΈ Vite + Tailwind + alias config
βββ jsconfig.json # π§ Editor alias support
βββ tailwind.config.js # π¨ Auto-generated by Shadcn (optional to tweak)
βββ package.json
βββ ...
π§ Pro Tip: Keep
src/components/ui/for Shadcn primitives, and createsrc/components/for your custom composables (e.g.,UserProfile.jsx,NavBar.jsx).
π οΈ Troubleshooting Quick Fixes
| Issue | Solution |
|---|---|
β @/ imports not working |
Restart VS Code; ensure jsconfig.json is at root |
| β Tailwind classes not applying | Verify @import "tailwindcss" is in index.css
|
| β Shadcn components look unstyled | Check that index.css is imported in main.jsx
|
| β Vite server won't start | Run npm run dev -- --force to clear HMR cache |
| β Button has no hover effect | Ensure tailwind.config.js includes content paths (Shadcn auto-generates this) |
π§ͺ Bonus: Add a Dark Mode Toggle (Optional)
Shadcn supports theming out of the box! Add this to src/App.jsx:
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
export default function App() {
const [dark, setDark] = useState(false);
useEffect(() => {
document.documentElement.classList.toggle("dark", dark);
}, [dark]);
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-background text-foreground transition-colors">
<Button onClick={() => setDark(!dark)} variant="outline">
{dark ? "βοΈ Light Mode" : "π Dark Mode"}
</Button>
</div>
);
}
π Requires
darkMode: "class"intailwind.config.js(Shadcn sets this by default).
π Helpful Resources
π― Key Takeaways
- β Vite = Blazing-fast dev server & build
- β
@tailwindcss/vite= Simpler Tailwind setup (no PostCSS!) - β
@/aliases = Cleaner, scalable imports - β Shadcn UI = Production-ready, accessible components β you own the code
- β JavaScript-first = No TypeScript overhead for quick prototyping
π If this guide helped you ship faster, give it a β€οΈ, share it with your team, or drop a comment with what you're building!
Top comments (0)