Tailwind CSS
Learn how to use Tailwind CSS v4 in your Bini.js application with zero configuration.
Tailwind CSS v4 is the default styling option in Bini.js. It is pre-configured using the official Vite plugin - no PostCSS configuration needed.
@tailwindcss/vite plugin. Everything works out of the box - no postcss.config.js or tailwind.config.js required.Setup
When you create a new Bini.js project with Tailwind, everything is configured automatically. Use the --tailwind flag:
$ npx create-bini-app@latest my-app --tailwind
Or use the interactive prompt and select Tailwind CSS under the styling question:
? Select a styling solution:> Tailwind CSSCSS ModulesNone↑↓ navigate • ⏎ select
Tailwind is the default, so you can also just run:
$ npx create-bini-app@latest my-app
With TypeScript + Tailwind:
$ npx create-bini-app@latest my-app --tailwind --typescript
Everything below is configured automatically:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import { biniroute } from 'bini-router'
export default defineConfig({
plugins: [
react(),
tailwindcss(), // Automatically added
biniroute(),
],
})/* src/app/globals.css */
@import 'tailwindcss';// src/app/layout.tsx
import './globals.css'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}Global CSS
Everything Tailwind related lives in one file, globals.css. It is imported once in the root layout, so the theme, base styles and custom utilities apply to every route:
/* src/app/globals.css */
@import 'tailwindcss';
/* Theme tokens - each one becomes a utility (bg-primary, rounded-card, ...) */
@theme {
--color-primary: #06b6d4;
--color-primary-dark: #0891b2;
--font-sans: 'Inter', system-ui, sans-serif;
--radius-card: 1rem;
}
/* Base styles applied to every page */
@layer base {
body {
font-family: var(--font-sans);
-webkit-font-smoothing: antialiased;
}
}
/* Custom utilities */
@utility text-gradient {
background: linear-gradient(to right, var(--tw-gradient-stops));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
@utility card-hover {
transition: all 0.2s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
}// src/app/layout.tsx
import './globals.css'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}@import 'tailwindcss' at the top of the file. The sections below show each part of this file in more detail.Basic Usage
Use Tailwind's utility classes directly in your components:
export default function HomePage() {
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-black">
<h1 className="bg-linear-to-r from-cyan-400 to-blue-500 bg-clip-text text-4xl font-bold text-transparent">
Welcome to Bini.js
</h1>
<p className="mt-4 text-lg text-slate-400">
Styled with Tailwind CSS v4
</p>
<button className="mt-6 rounded-lg bg-cyan-500 px-4 py-2 font-medium text-black transition-colors hover:bg-cyan-400">
Get Started
</button>
</div>
)
}Tailwind CSS v4 Features
| Feature | Description |
|---|---|
| Vite Plugin | Native Vite integration - no PostCSS config needed |
| CSS-first config | Configure via CSS variables instead of JS |
| Lightning CSS | Faster builds with Lightning CSS |
| Simplified setup | Just @import "tailwindcss" - that is it |
Theming with CSS Variables
Tailwind v4 uses CSS variables for theming. Every token you declare in @theme becomes a utility:
/* src/app/globals.css */
@import 'tailwindcss';
@theme {
--color-primary: #06b6d4;
--color-primary-dark: #0891b2;
--font-sans: 'Inter', system-ui, sans-serif;
--radius-card: 1rem;
}// src/app/components/Card.tsx
export function Card({ children }: { children: React.ReactNode }) {
return (
<div className="rounded-(--radius-card) bg-primary p-6">
{children}
</div>
)
}Responsive Design
Use Tailwind's responsive prefixes to adapt your layout:
export default function ResponsivePage() {
return (
<div className="container mx-auto px-4">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
{[...Array(3)].map((_, i) => (
<div key={i} className="rounded-lg bg-slate-900 p-4">
<h2 className="text-lg font-semibold text-white sm:text-xl">
Card {i + 1}
</h2>
</div>
))}
</div>
</div>
)
}| Breakpoint | Min Width |
|---|---|
| sm | 640px |
| md | 768px |
| lg | 1024px |
| xl | 1280px |
| 2xl | 1536px |
Dark Mode
Use the dark: variant for dark mode:
export function ThemeToggle() {
return (
<div className="rounded-lg bg-white p-4 dark:bg-slate-900">
<h2 className="text-slate-900 dark:text-white">
Theme Aware Component
</h2>
<p className="text-slate-600 dark:text-slate-400">
This adapts to light and dark mode
</p>
</div>
)
}Custom Utilities
Create custom utilities using @utility:
/* src/app/globals.css */
@import 'tailwindcss';
@utility text-gradient {
background: linear-gradient(to right, var(--tw-gradient-stops));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
@utility card-hover {
transition: all 0.2s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
}export function FeatureCard() {
return (
<div className="card-hover rounded-lg bg-slate-900 p-6">
<h3 className="text-gradient from-cyan-400 to-blue-500 text-xl font-bold">
Custom Utility
</h3>
</div>
)
}Common Patterns
Container
// src/app/components/Container.tsx
export function Container({ children }: { children: React.ReactNode }) {
return (
<div className="container mx-auto px-4">
{children}
</div>
)
}Flex Center
// src/app/components/FlexCenter.tsx
export function FlexCenter({ children }: { children: React.ReactNode }) {
return (
<div className="flex items-center justify-center">
{children}
</div>
)
}Grid Layout
// src/app/components/GridLayout.tsx
export function GridLayout({ children }: { children: React.ReactNode }) {
return (
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{children}
</div>
)
}Button Styles
export function Buttons() {
return (
<div className="flex gap-3">
{/* Primary */}
<button className="rounded-lg bg-cyan-500 px-4 py-2 font-medium text-black hover:bg-cyan-400">
Primary
</button>
{/* Secondary */}
<button className="rounded-lg border border-slate-700 px-4 py-2 text-white hover:bg-slate-900">
Secondary
</button>
</div>
)
}