CSS

Learn about the different ways to add CSS to your Bini.js application.

Bini.js provides several ways to style your application. You can use Tailwind CSS v4 (default), CSS Modules, or plain CSS — choose what works best for your project.

Styling Options

OptionDescriptionBest For
Tailwind CSS v4Utility-first CSS framework with Vite plugin (default)Rapid development, consistent design
CSS ModulesLocally scoped CSS by defaultComponent-specific styles, avoiding conflicts
Global CSSTraditional stylesheet applied globallyBase styles, resets, utilities
NoneNo styling — bring your ownCustom setups, CSS-in-JS libraries

Tailwind CSS v4

Tailwind CSS v4 is pre-configured using the official Vite plugin. No PostCSS configuration needed — it just works.

Zero Configuration: Bini.js uses the @tailwindcss/vite plugin. Everything is configured automatically — no postcss.config.js or tailwind.config.js required.
app/page.tsx
// src/app/page.tsx
export default function HomePage() {
  return (
    <div className="flex min-h-screen flex-col items-center justify-center">
      <h1 className="text-4xl font-bold text-cyan-400">
        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 text-black hover:bg-cyan-400">
        Get Started
      </button>
    </div>
  )
}

The global CSS file simply imports Tailwind:

app/globals.css
/* src/app/globals.css */
@import 'tailwindcss';

The Vite config includes the Tailwind plugin automatically:

vite.config.ts
// vite.config.ts
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 when Tailwind is selected
    biniroute(),
  ],
})

CSS Modules

CSS Modules scope styles locally to avoid naming conflicts. Files must end with .module.css:

Button.module.css
/* src/app/components/Button.module.css */
.button {
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  font-weight: 500;
  transition: all 0.2s;
}

.primary {
  background: #06b6d4;
  color: black;
}

.primary:hover {
  background: #0891b2;
}
Button.tsx
// src/app/components/Button.tsx
import styles from './Button.module.css'

export function Button({ variant = 'primary', children }) {
  return (
    <button className={`${styles.button} ${styles[variant]}`}>
      {children}
    </button>
  )
}
CSS Modules are processed by Vite automatically — no configuration needed.

Global CSS

Import CSS files directly to apply styles globally:

app/globals.css
/* src/app/globals.css */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: system-ui, -apple-system, sans-serif;
  background: black;
  color: white;
}
app/layout.tsx
// src/app/layout.tsx
import './globals.css'

export default function RootLayout() {
  return <Outlet />
}

None Option

Choose --none during project creation for a clean slate:

npx create-bini-app@latest my-app --none
Even with --none, Vite still handles .css imports natively. You can add any CSS file and it will work.

External Stylesheets

Import styles from npm packages or external URLs:

app/layout.tsx
// src/app/layout.tsx
import 'bootstrap/dist/css/bootstrap.min.css'
import 'animate.css'

export default function RootLayout() {
  return <Outlet />
}

CSS Ordering

CSS is applied in the order you import it:

import './globals.css'        // Base styles first
import './utilities.css'      // Utilities second
import styles from './Component.module.css'  // Component styles last
Keep CSS imports in a consistent order to avoid specificity issues. Global styles → utilities → component styles.

Sass/SCSS Support

Vite has built-in support for Sass:

npm install -D sass
Card.module.scss
/* src/app/components/Card.module.scss */
.card {
  background: #0a0a0a;
  border: 1px solid #1e293b;
  padding: 1.5rem;
  border-radius: 0.75rem;
  
  &:hover {
    border-color: #06b6d4;
  }
}
Vite handles Sass compilation automatically. No additional configuration needed.

CSS-in-JS

Use CSS-in-JS libraries with the --none option:

npm install styled-components
StyledButton.tsx
// src/app/components/StyledButton.tsx
import styled from 'styled-components'

const Button = styled.button`
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  background: #06b6d4;
  color: black;
  cursor: pointer;
  
  &:hover {
    background: #0891b2;
  }
`

export function StyledButton({ children }) {
  return <Button>{children}</Button>
}

CSS Variables for Theming

Define CSS variables for consistent theming:

app/globals.css
/* src/app/globals.css */
:root {
  --bg-primary: #000000;
  --text-primary: #ffffff;
  --accent: #06b6d4;
  --border: #1e293b;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg-primary: #ffffff;
    --text-primary: #0f172a;
    --border: #e2e8f0;
  }
}

body {
  background: var(--bg-primary);
  color: var(--text-primary);
}