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!
























