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!