Getting Started

Components

Installation

Bring the aggressive, bold Neo Brutalism aesthetic to any web project. Fully framework-agnostic!

1. The CSS Plugin (For HTML, Vue, React, PHP)

Install the core Tailwind CSS plugin via NPM. This works everywhere Tailwind works.

npm install neo-brutalism-tailwind

Method A: Tailwind CSS v4 (New Standard)

If you are using Tailwind v4, simply import the plugin in your main CSS file (e.g., input.css or app.css):

@import "tailwindcss";
@plugin "neo-brutalism-tailwind";

Method B: Tailwind CSS v3 (Legacy / Typical Laravel)

If you are using Tailwind v3, add the plugin to your tailwind.config.js:

module.exports = {
  content: [
    "./**/*.html",
    "./**/*.php",
    "./src/**/*.{vue,js,ts,jsx,tsx}"
  ],
  plugins: [
    require('neo-brutalism-tailwind')()
  ],
}

2. Laravel Blade Integration (Optional)

If you are using Laravel, we provide a specialized Blade component package for a better developer experience.

composer require vr/laravel-neo-ui

3. Real Project Sample

Want to see a fully working, standalone project with a real build step? Check out the sample folder in our repository!

View Sample Project on GitHub

Configuration

Learn how to customize prefixes to prevent CSS conflicts.

Adding a Custom Prefix

If you don't want our classes (like .btn) to conflict with Bootstrap or other libraries, you can add a prefix.

1. In tailwind.config.js:

plugins: [
    require('neo-brutalism-tailwind')({ prefix: 'neo-' })
]

Now all components will be prefixed (e.g., class="neo-btn").

2. In Laravel (Optional):

Publish the config and update it so Blade components match your Tailwind prefix.

php artisan vendor:publish --tag=neo-ui-config
// config/neo-ui.php
return [
    'prefix' => 'neo-',
];

Dark Mode

Learn how to easily toggle between light and dark modes.

Enabling Dark Mode

Neo Brutalism UI respects the dark class on your HTML <html> element to switch to dark mode. It natively integrates with Tailwind's class-based dark mode.

1. Enable class-based dark mode in Tailwind configuration:

// tailwind.config.js
module.exports = {
  darkMode: 'class', // Add this line
  // ...
}

2. Toggle using JavaScript or Alpine.js:

To activate dark mode, simply add the dark class to the <html> element. Below is an example using Alpine.js and a toggle switch:

<html lang="en" :class="{ 'dark': isDark }" x-data="{ isDark: false }">
    <body>
        <label class="flex items-center gap-2 cursor-pointer font-bold">
            <input type="checkbox" class="toggle" x-model="isDark" />
            Toggle Dark Mode
        </label>
    </body>
</html>

Button

The primary action element with click and hover states.

Pure HTML Usage:

<button class="btn btn-sm">Small</button>
<button class="btn">Default</button>
<button class="btn btn-lg">Large</button>

<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-danger">Danger</button>
<button class="btn btn-info">Info</button>
<button class="btn" disabled>Disabled</button>

Laravel Blade Usage:

<x-neo::button class="btn-sm">Small</x-neo::button>
<x-neo::button>Default</x-neo::button>
<x-neo::button class="btn-lg">Large</x-neo::button>

<x-neo::button variant="primary">Primary</x-neo::button>
<x-neo::button variant="secondary">Secondary</x-neo::button>
<x-neo::button variant="danger">Danger</x-neo::button>
<x-neo::button variant="info">Info</x-neo::button>
<x-neo::button disabled>Disabled</x-neo::button>

Forms & Inputs

Text inputs, textareas, selects, toggles, checkboxes, and more.

Pure HTML Usage:

<input type="email" class="input" placeholder="Email" />
<textarea class="textarea" placeholder="Message"></textarea>
<select class="select">
    <option>Option 1</option>
</select>

<input type="file" class="file-input" />
<input type="range" class="range" min="0" max="100" />

<input type="checkbox" class="toggle" checked />
<input type="checkbox" class="checkbox" checked />
<input type="radio" class="radio" />

Laravel Blade Usage:

<x-neo::input type="email" placeholder="Email" />
<x-neo::textarea placeholder="Message"></x-neo::textarea>
<x-neo::select>
    <option>Option 1</option>
</x-neo::select>

<x-neo::file-input />
<x-neo::range min="0" max="100" />

<x-neo::toggle checked />
<x-neo::checkbox checked />
<x-neo::radio />

Data Display

Table

# IDNameRoleStatus
1John DoeAdminActive
2Jane SmithUserPending

Avatars

Avatar 1
Avatar 2
Avatar 3

Accordion

Click me to expand #1
Here is the content for the accordion.
Click me to expand #2
More content for the second item!

Tabs

Home
Profile

Welcome Home!

Your Profile Data

Pure HTML Usage:

<table class="table">
    <thead>...</thead>
    <tbody>...</tbody>
</table>

<div class="avatar w-16 h-16">
    <img src="image.jpg" alt="Profile" />
</div>
<div class="avatar w-20 h-20 rounded-full">
    <img src="image.jpg" alt="Profile" />
</div>

<details class="accordion">
    <summary>Title</summary>
    <div class="accordion-content">Content...</div>
</details>

Laravel Blade Usage:

<x-neo::table>
    <thead>...</thead>
    <tbody>...</tbody>
</x-neo::table>

<x-neo::avatar src="image.jpg" class="w-16 h-16" />
<x-neo::avatar src="image.jpg" class="w-20 h-20 rounded-full" />

<x-neo::accordion title="Title">
    Content...
</x-neo::accordion>

Navigation & Alerts

Badges

Default Primary Secondary Danger Info

Alerts

Default Alert Message
Success! Everything went well.
Error! Something went wrong.
Warning! Your session will expire soon.
Info: New updates are available.

Pagination

Modals & Toasts (Require Alpine.js)

Pure HTML Usage:

<span class="badge">Default</span>
<span class="badge badge-primary">Primary</span>
<span class="badge badge-secondary">Secondary</span>
<span class="badge badge-danger">Danger</span>
<span class="badge badge-info">Info</span>

<div class="alert alert-success">Success Message</div>
<div class="alert alert-danger">Error Message</div>
<div class="alert alert-warning">Warning Message</div>
<div class="alert alert-info">Info Message</div>

<div class="pagination">
    <div class="page-item">1</div>
    <div class="page-item page-active">2</div>
</div>

Laravel Blade Usage:

<x-neo::badge>Default</x-neo::badge>
<x-neo::badge variant="primary">Primary</x-neo::badge>
<x-neo::badge variant="secondary">Secondary</x-neo::badge>
<x-neo::badge variant="danger">Danger</x-neo::badge>
<x-neo::badge variant="info">Info</x-neo::badge>

<x-neo::alert variant="success">Success Message</x-neo::alert>
<x-neo::alert variant="danger">Error Message</x-neo::alert>
<x-neo::alert variant="warning">Warning Message</x-neo::alert>
<x-neo::alert variant="info">Info Message</x-neo::alert>

<x-neo::pagination>...</x-neo::pagination>

Icons (Lucide)

Neo UI bundles Lucide Icons out of the box via the mallardduck/blade-lucide-icons package.

Using Icons inside Components

Most components like Buttons, Inputs, Alerts, and Badges support the icon attribute directly. The component will automatically handle the SVG rendering and spacing.

Buttons with Icons:

Alerts with Icons:

Watch out! This action cannot be undone.

Inputs with Icons:

Pure HTML Usage:

Include our neo-icons.js script alongside Lucide JS, and you can write cleaner HTML.

<!-- Button -->
<button class="btn btn-primary" icon="send">
    Send Message
</button>

<!-- Input -->
<input type="text" class="input" icon="search" placeholder="Search...">

<!-- Alert -->
<div class="alert alert-warning" icon="triangle-alert">
    <div>Watch out!</div>
</div>

<!-- Standalone Icon -->
<icon name="home" class="text-blue-500"></icon>

Laravel Blade Usage:

Simply pass the icon name to the component properties.

<!-- Button -->
<x-neo::button variant="primary" icon="send">
    Send Message
</x-neo::button>

<x-neo::button iconRight="arrow-right">
    Next Step
</x-neo::button>

<!-- Input -->
<x-neo::input icon="search" placeholder="Search..." />

<!-- Alert -->
<x-neo::alert variant="warning" icon="triangle-alert">
    Watch out!
</x-neo::alert>

<!-- Freeform Icon Wrapper -->
<x-neo::icon name="home" class="w-8 h-8 text-blue-500" />