React and Tailwind CSS are a powerful combo for building modern web applications. React gives you component-based architecture, while Tailwind CSS provides utility-first styling that helps you build fast and consistent UIs.
In this post, we’ll walk you through how to use React with Tailwind CSS and share some best practices to help you build scalable UI components — even if you’re just starting out.
Why Use Tailwind CSS with React?
Before diving into best practices, let’s understand why Tailwind CSS works so well with React:
* Utility-first: Tailwind helps you style directly in your JSX without writing custom CSS.
* Consistent design: Reuse utility classes instead of rewriting styles.
* Customizable: Easily adjust your design system using Tailwind's configuration file.
* Component-friendly: React components pair naturally with utility classes.
Setting Up React with Tailwind CSS
If you’re using Create React App, here's how to set up Tailwind:
npx create-react-app my-app
cd my-app
npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init
Then update tailwind.config.js:
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
And add Tailwind to your src/index.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
You’re all set! Now let’s talk about building UI components the right way.
Best Practices for Scalable UI Components
1. Build Reusable Components
React is all about reusability. Break down your UI into small, focused components.
function Button({ children, onClick }) {
return (
<button
onClick={onClick}
className="bg-blue-600 text-white py-2 px-4 rounded hover:bg-blue-700"
>
{children}
</button>
);
}
export default Button
Now you can reuse <Button> anywhere and pass different content or actions.
2. Use Tailwind’s Custom Classes with @apply
If a component has too many utility classes, move styles into a custom class using @apply.
/* src/index.css */
.btn-primary {
@apply bg-blue-600 text-white py-2 px-4 rounded hover:bg-blue-700;
}
function Button({ children, onClick }) {
return (
<button onClick={onClick} className="btn-primary">
{children}
</button>
);
}
export default Button
This keeps your JSX clean and maintainable.
3. Use Variants and Props for Flexibility
Make your components dynamic with props.
function Button({ children, variant = "primary" }) {
const base = "py-2 px-4 rounded font-medium";
const styles = {
primary: "bg-blue-600 text-white hover:bg-blue-700",
secondary: "bg-gray-200 text-black hover:bg-gray-300",
};
return (
<button className={`${base} ${styles[variant]}`}>
{children}
</button>
);
}
export default Button
Now use it like:
<Button variant="secondary">Cancel</Button>
4. Keep Layout and Logic Separate
Use wrapper components for layout and keep logic-focused components lean.
export default function Card({ title, children }) {
return (
<div className="bg-white shadow-md rounded-lg p-4">
<h2 className="text-lg font-bold mb-2">{title}</h2>
{children}
</div>
);
}
5. Use Tailwind Plugins and Config
Customize your Tailwind config to match your design system (e.g., brand colors, font sizes).
// tailwind.config.js
theme: {
extend: {
colors: {
brand: '#1e40af',
},
},
}
Use it like: className="bg-brand".
6. Name Your Components Clearly
Choose clear, consistent names for components: PrimaryButton, UserCard, DashboardHeader, etc. This helps keep large codebases understandable.
7. Group UI Components by Domain
Organize files like this:
src/
components/
ui/
Button.jsx
Card.jsx
dashboard/
DashboardHeader.jsx
StatsCard.jsx
Separate generic UI elements from domain-specific components.
Tailwind gives you fast styling, and React gives you scalable architecture. Together, they help you ship faster and keep your UI consistent and clean.
To read more about How to Connect a React Frontend with Odoo's REST API, refer to our blog How to Connect a React Frontend with Odoo's REST API.