CSS-Only Tailwind CSS v4 UI Components – Frutjam

Category: CSS & CSS3 | October 8, 2026
Authornezanuha
Last UpdateOctober 8, 2026
LicenseMIT
Views0 views
CSS-Only Tailwind CSS v4 UI Components – Frutjam

Frutjam is a CSS-only UI component library for Tailwind CSS v4 that styles buttons, forms, navigation, dialogs, tabs, and other web elements.

It includes reusable classes and light and dark themes built on OKLCH color tokens.

Frutjam also works through an UnoCSS preset or a compiled stylesheet for plain HTML.

It also comes with JavaScript helpers for programmatic dialog controls, tabs, toasts, and searchable comboboxes.

Features

  • 50+ CSS UI components for forms, layouts, feedback, and data display.
  • CSS variables for OKLCH-based light, dark, and custom themes.
  • Tailwind CSS v4 plugin with responsive variants and selective component loading.
  • UnoCSS preset and a compiled stylesheet for projects outside Tailwind.
  • Optional framework-independent JavaScript helpers for interactive components.
  • React hooks for dialogs, drawers, tabs, carousels, notifications, and more.
  • Component class prefixes and scoped theme tokens for CSS integration.

Use Cases

  • Admin dashboards with navigation, forms, status labels, data tables, and dialogs.
  • Server-rendered Django, Laravel Blade, or HTMX screens that use plain HTML classes.
  • Content sites and marketing pages that need consistent headings, cards, buttons, and themes.

How To Use It

Installation

Install frutjam with NPM:

npm install -D frutjam

Import Tailwind CSS and register the Frutjam plugin in the stylesheet processed by Tailwind:

@import "tailwindcss";
@plugin "frutjam";

Basic Usage

Use Frutjam classes in regular HTML. Set a theme on a parent element. This card example has a labeled email input, a status badge, and a save button.

<section class="wrapper-md" data-theme="snowberry">
  <div class="card card-outline">
    <div class="card-content">
      <h2 class="card-title">Workspace settings</h2>
      <p class="para-base">Manage your team's workspace.</p>
      <label for="team-email">Contact email</label>
      <input id="team-email" type="email" class="input"
             placeholder="[email protected]">
      <div class="card-actions">
        <button type="button" class="btn btn-primary">Save changes</button>
        <span class="badge badge-success">Active</span>
      </div>
    </div>
  </div>
</section>

Using Frutjam Without Tailwind CSS

The precompiled components bundle includes Frutjam’s base styles, default themes, components, and component utilities. It does not contain the general-purpose Tailwind utility library (flex, grid, p-4, etc.). Use standard CSS or your existing utility system for any additional layout styles.

For a bundler that accepts CSS imports:

import 'frutjam/css';

For a static HTML page, load the components-only CSS build. It does not include Tailwind utility classes. The @2 release selector follows version 2 updates; pin an exact release for production deployments.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/frutjam@2/dist/frutjam.components.css">
<button type="button" class="btn btn-primary">Save</button>
<span class="badge badge-success">Published</span>

Including Tailwind Utilities Without a Build Step

The full Frutjam CSS distribution includes Tailwind’s general-purpose utilities as well as the component styles. Load this file when a static page needs classes such as flex, grid, and p-4.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/frutjam@2/dist/frutjam.min.css">

A bundler can import this file through frutjam/css/full:

import 'frutjam/css/full';

Using the UnoCSS Preset

Frutjam exposes presetFrutjam() for UnoCSS projects. Use UnoCSS 66 or newer and configure its Wind4 preset before loading Frutjam.

// uno.config.js
import { defineConfig, presetWind4 } from 'unocss';
import { presetFrutjam } from 'frutjam/unocss';
export default defineConfig({
  presets: [presetWind4(), presetFrutjam()],
});

Interactive Combobox With Vanilla JavaScript

Use the optional JavaScript helper for a searchable combobox with keyboard navigation and selection events. The parent needs position: relative for its popup list. The following HTML uses Tailwind utility classes and a bundler that resolves frutjam/js.

<div id="framework-picker" class="relative w-64">
  <label for="framework-search">Framework</label>
  <input id="framework-search" class="input" type="text"
         placeholder="Search frameworks">
  <ul class="combobox-list" role="listbox">
    <li class="combobox-item" role="option" data-value="react">React</li>
    <li class="combobox-item" role="option" data-value="vue">Vue</li>
    <li class="combobox-item" role="option" data-value="svelte">Svelte</li>
  </ul>
</div>
import { createCombobox } from 'frutjam/js';
const picker = document.querySelector('#framework-picker');
createCombobox(picker);
picker.addEventListener('fj:select', (event) => {
  console.log(event.detail.value);
});

Displaying Toast Notifications

A static toast container needs only CSS, but notifications created from application events use the optional toast manager. duration: 0 keeps the message in the container until it is dismissed.

<div id="messages" class="toast toast-top toast-end"></div>
import { createToastManager } from 'frutjam/js';
const messages = createToastManager(document.querySelector('#messages'));
messages.success('Settings saved', { duration: 3500 });

Tailwind Plugin Configuration Options

Pass Frutjam plugin settings through an @plugin block. include and exclude use comma-separated component identifiers. If include contains entries, it takes precedence over exclude.

@import "tailwindcss";
@plugin "frutjam" {
  prefix: fj;
  reset: false;
  root: #admin;
  include: button, card, alert, badge;
  logs: false;
}
OptionDefaultPurpose
prefix""Prefix component class names, e.g. fj-btn.
resettrueInclude Frutjam’s base element resets.
root:rootScope theme tokens to :root, :host, or another selector.
logstruePrint Frutjam’s build-time console banner.
include[]Include only the listed components and utilities.
exclude[]Exclude the listed components and utilities.

Class Prefixes With Tailwind

The Tailwind import prefix and Frutjam’s component prefix are independent. The first is a variant prefix, whereas the second changes Frutjam’s class names.

@import "tailwindcss" prefix(tw);
@plugin "frutjam" {
  prefix: fj;
}
<button type="button" class="tw:fj-btn tw:fj-btn-primary">
  Send message
</button>

UnoCSS Preset Options

presetFrutjam() accepts these three options:

OptionDefaultPurpose
preflighttrueInclude Frutjam’s base styles and themes.
prefix""Prefix Frutjam component class names.
layer"frutjam"Choose the CSS cascade layer for the preset.

Themes And CSS Variables

Use data-theme on the root element or on any container. The package includes Snowberry (snowberry or light) and Darkberry (darkberry or dark). Other palettes require custom theme values.

<main data-theme="snowberry">
  <section data-theme="darkberry">
    <button class="btn btn-primary">Dark section</button>
  </section>
</main>

Custom Themes

For custom themes, set the design tokens inside @layer theme. Choose foreground and background colors as matching pairs, and check contrast after changing the defaults.

@layer theme {
  [data-theme="forest"] {
    --scheme-color: dark;
    --border-radius: 0.5rem;
    --color-base: oklch(19% 0.03 155);
    --color-on-base: oklch(96% 0.02 155);
    --color-primary: oklch(72% 0.15 150);
    --color-on-primary: oklch(16% 0.02 150);
  }
}

Theme Token Reference

Root theme tokens use matching background and foreground color pairs. on-* variables supply the foreground colors.

CSS VariablePurpose
--scheme-colorLight or dark color scheme.
--border-radiusBase radius for Frutjam components.
--color-base, --color-on-basePage background and default text.
--color-neutral, --color-on-neutralNeutral surfaces and their foreground text.
--color-primary, --color-on-primaryPrimary color and contrasting content.
--color-secondary, --color-on-secondarySecondary color and contrasting content.
--color-accent, --color-on-accentAccent color and contrasting content.
--color-info, --color-on-infoInformational color and contrasting content.
--color-success, --color-on-successSuccess color and contrasting content.
--color-warning, --color-on-warningWarning color and contrasting content.
--color-error, --color-on-errorError color and contrasting content.

Generated Color Tokens

Each color role also has these generated tokens. {color} stands for base, neutral, primary, secondary, accent, info, success, warning, or error.

TokenPurpose
--color-{color}-50Lightest generated tint.
--color-{color}-100Light tint.
--color-{color}-200Light tint.
--color-{color}-300Medium-light tint.
--color-{color}-400Subtle tint.
--color-{color}-500Base color.
--color-{color}-600First darker shade.
--color-{color}-700Medium-dark shade.
--color-{color}-800Dark shade.
--color-{color}-900Very dark shade.
--color-{color}-950Darkest generated shade.
--color-{color}-softSoft variant background.
--color-on-{color}-softForeground on a soft background.
--color-{color}-activeInteractive active-state color.
--color-bodyDerived body text color.

Color Utility Families

For {color} roles, Tailwind CSS utilities use the semantic theme colors. These are the color utility families.

Class PatternPurpose
bg-{color}Background color.
text-{color}Text color.
border-{color}Border color.
ring-{color}Ring color.
outline-{color}Outline color.
shadow-{color}Shadow color.
fill-{color}SVG fill.
stroke-{color}SVG stroke.
decoration-{color}Text decoration.
caret-{color}Input caret.
placeholder-{color}Placeholder text.
divide-{color}Divider border color.

Typography And Layout Classes

The complete wrapper width series is wrapper, wrapper-xs, wrapper-sm, wrapper-md, wrapper-lg, wrapper-xl, wrapper-2xl, and wrapper-full.

Heading and paragraph classes accept standard sizes and numeric pixel values, including heading-46 and para-28.

Class FamilyValues
heading-{size}xs, sm, md, base, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, 8xl, 9xl
para-{size}xs, sm, md, base, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, 8xl, 9xl
prose prose-frutjamRich text styled with Frutjam theme tokens; requires @tailwindcss/typography.
prose-invertInverted prose variant for dark backgrounds.

Component CSS Class Reference

Frutjam CSS components use base classes plus modifiers for colors, sizes, layout, and state. The class inventory below includes their CSS utilities. Tailwind utility classes are configured through Tailwind itself.

Inputs & Forms

ComponentCSS Classes
Buttonbtn, btn-primary, btn-secondary, btn-accent, btn-info, btn-neutral, btn-success, btn-warning, btn-error, btn-square, btn-rounded, btn-pill, btn-circle, btn-xs, btn-sm, btn-md, btn-lg, btn-xl, btn-2xl, btn-wide, btn-block, btn-active, btn-disabled, btn-soft, btn-dashed, btn-outline, btn-ghost, btn-plain, btn-link
Checkboxcheckbox, checkbox-primary, checkbox-secondary, checkbox-accent, checkbox-info, checkbox-neutral, checkbox-success, checkbox-warning, checkbox-error, checkbox-circle, checkbox-rounded, checkbox-square, checkbox-xs, checkbox-sm, checkbox-md, checkbox-lg, checkbox-xl, checkbox-2xl, checkbox-disabled
Radioradio, radio-primary, radio-secondary, radio-accent, radio-info, radio-neutral, radio-success, radio-warning, radio-error, radio-circle, radio-rounded, radio-square, radio-xs, radio-sm, radio-md, radio-lg, radio-xl, radio-2xl, radio-disabled
Toggletoggle, toggle-primary, toggle-secondary, toggle-accent, toggle-neutral, toggle-info, toggle-success, toggle-warning, toggle-error, toggle-xs, toggle-sm, toggle-md, toggle-lg, toggle-xl
Inputinput, input-primary, input-secondary, input-neutral, input-accent, input-info, input-success, input-warning, input-error, input-xs, input-sm, input-md, input-lg, input-xl, input-2xl, input-disabled, input-dashed, input-outline, input-soft, input-ghost, input-square
Textareatextarea, textarea-primary, textarea-secondary, textarea-accent, textarea-neutral, textarea-info, textarea-success, textarea-warning, textarea-error, textarea-xs, textarea-sm, textarea-md, textarea-lg, textarea-xl, textarea-2xl, textarea-soft, textarea-ghost, textarea-dashed
Selectselect, select-primary, select-secondary, select-neutral, select-accent, select-info, select-success, select-warning, select-error, select-xs, select-sm, select-md, select-lg, select-xl, select-2xl, select-soft, select-ghost, select-dashed
Rangerange, range-primary, range-secondary, range-accent, range-neutral, range-info, range-success, range-warning, range-error, range-xs, range-sm, range-md, range-lg, range-xl
Ratingrating, rating-half, rate, rate-primary, rate-secondary, rate-accent, rate-neutral, rate-info, rate-success, rate-warning, rate-error, rating-xs, rating-sm, rating-md, rating-lg, rating-xl
Comboboxcombobox-list, combobox-item, combobox-open, combobox-primary, combobox-secondary, combobox-accent, combobox-info, combobox-success, combobox-warning, combobox-error

Layout & Navigation

ComponentCSS Classes
Navbarnavbar, navbar-start, navbar-center, navbar-end, navbar-top, navbar-middle, navbar-bottom, navbar-list
Sidebarsidebar
Drawerdrawer, drawer-top, drawer-bottom, drawer-start, drawer-end, drawer-backdrop, drawer-content
Menumenu, menu-horizontal, menu-vertical, menu-disabled, menu-active, menu-xs, menu-sm, menu-md, menu-lg, menu-xl, menu-title, menu-item
Breadcrumbbreadcrumb, breadcrumb-link, breadcrumb-current, breadcrumb-list, breadcrumb-item, breadcrumb-separator
Tabstabs, tab, tab-active, tab-disabled, tab-content, tabs-underline, tabs-box, tabs-bottom, tabs-lifted, tabs-end, tabs-vertical, tabs-xs, tabs-sm, tabs-md, tabs-lg, tabs-xl
Stepssteps, step, steps-horizontal, steps-vertical, step-primary, step-secondary, step-accent, step-neutral, step-info, step-success, step-warning, step-error
Footerfooter, footer-center, footer-title, footer-horizontal, footer-vertical
Headerheader, header-sticky, header-fixed, header-shadow, header-blur, header-transparent, header-solid, header-sm, header-lg, header-content, header-start, header-center, header-end
Joinjoin, join-horizontal, join-vertical, join-item

Feedback & Overlay

ComponentCSS Classes
Modalmodal, modal-slide-up, modal-slide-down, modal-slide-start, modal-slide-end, modal-start, modal-center, modal-end, modal-top, modal-middle, modal-bottom, modal-backdrop, modal-content
Toasttoast, toast-start, toast-center, toast-end, toast-top, toast-middle, toast-bottom
Alertalert, alert-primary, alert-secondary, alert-accent, alert-info, alert-neutral, alert-success, alert-warning, alert-error, alert-dashed, alert-outline, alert-soft, alert-ghost, alert-rounded, alert-pill, alert-xs, alert-sm, alert-md, alert-lg, alert-horizontal, alert-vertical
Tooltiptooltip, tooltip-primary, tooltip-secondary, tooltip-accent, tooltip-neutral, tooltip-info, tooltip-success, tooltip-warning, tooltip-error, tooltip-top, tooltip-bottom, tooltip-left, tooltip-right, tooltip-start, tooltip-end, tooltip-content
Popoverpopover, popover-toggle, popover-content, popover-hover, popover-top-start, popover-top-center, popover-top-end, popover-end-top, popover-end-center, popover-end-bottom, popover-bottom-start, popover-bottom-center, popover-bottom-end, popover-start-top, popover-start-center, popover-start-bottom
Loadingloading, loading-base, loading-current, loading-primary, loading-secondary, loading-accent, loading-neutral, loading-info, loading-success, loading-warning, loading-error, loading-xs, loading-sm, loading-md, loading-lg, loading-xl, loading-dots, loading-bars
Skeletonskeleton, skeleton-circle, skeleton-text
Progressprogress, progress-primary, progress-secondary, progress-accent, progress-info, progress-neutral, progress-success, progress-warning, progress-error
Radial Progressradial-progress, radial-progress-base, radial-progress-current, radial-progress-primary, radial-progress-secondary, radial-progress-accent, radial-progress-neutral, radial-progress-info, radial-progress-success, radial-progress-warning, radial-progress-error, radial-progress-xs, radial-progress-sm, radial-progress-md, radial-progress-lg, radial-progress-xl

Data Display

ComponentCSS Classes
Cardcard, card-xs, card-sm, card-md, card-lg, card-xl, card-content, card-title, card-actions, card-link, card-outline, card-dashed, card-primary, card-secondary, card-accent, card-info, card-neutral, card-success, card-warning, card-error
Tabletable, table-xs, table-sm, table-md, table-lg, table-xl, table-hover, table-zebra, table-zebra-rows, table-zebra-cols, table-pin-rows, table-pin-cols
Statstats, stat, stat-title, stat-value, stat-desc, stat-figure, stats-horizontal, stats-vertical, stat-primary, stat-secondary, stat-accent, stat-neutral, stat-info, stat-success, stat-warning, stat-error
Badgebadge, badge-primary, badge-secondary, badge-accent, badge-info, badge-neutral, badge-success, badge-warning, badge-error, badge-square, badge-rounded, badge-pill, badge-circle, badge-xs, badge-sm, badge-md, badge-lg, badge-xl, badge-2xl, badge-dashed, badge-outline, badge-soft, badge-ghost
Tagtag, tag-remove, tag-primary, tag-secondary, tag-accent, tag-neutral, tag-info, tag-success, tag-warning, tag-error, tag-xs, tag-sm, tag-md, tag-lg, tag-xl, tag-soft, tag-outline, tag-square
Avataravatar, avatar-ring, avatar-online, avatar-offline, avatar-busy, avatar-away, avatar-group, avatar-primary, avatar-secondary, avatar-accent, avatar-info, avatar-neutral, avatar-success, avatar-warning, avatar-error, avatar-ring-primary, avatar-ring-secondary, avatar-ring-accent, avatar-ring-info, avatar-ring-neutral, avatar-ring-success, avatar-ring-warning, avatar-ring-error, avatar-xs, avatar-sm, avatar-md, avatar-lg, avatar-xl, avatar-2xl, avatar-circle, avatar-rounded, avatar-square
Indicatorindicator, indicator-item, indicator-start, indicator-end, indicator-center, indicator-top, indicator-middle, indicator-bottom
Statusstatus, status-primary, status-secondary, status-accent, status-neutral, status-info, status-success, status-warning, status-error, status-xs, status-sm, status-md, status-lg, status-xl
Diffdiff, diff-resizer, diff-item-1, diff-item-2
Timelinetimeline, timeline-item, timeline-start, timeline-middle, timeline-end, timeline-vertical, timeline-horizontal, timeline-snap-start, timeline-snap-end, timeline-primary, timeline-secondary, timeline-accent, timeline-neutral, timeline-info, timeline-success, timeline-warning, timeline-error
Chatchat, chat-start, chat-end, chat-avatar, chat-bubble, chat-header, chat-footer, chat-xs, chat-sm, chat-md, chat-lg, chat-xl, chat-bubble-primary, chat-bubble-secondary, chat-bubble-accent, chat-bubble-neutral, chat-bubble-info, chat-bubble-success, chat-bubble-warning, chat-bubble-error

Typography & Decoration

ComponentCSS Classes
Herohero, hero-overlay, hero-content
Dividerdivider, divider-primary, divider-secondary, divider-accent, divider-info, divider-neutral, divider-success, divider-warning, divider-error, divider-horizontal, divider-vertical, divider-start, divider-end, divider-solid, divider-dashed, divider-dotted
Kbdkbd, kbd-xs, kbd-sm, kbd-md, kbd-lg, kbd-xl
Linklink, link-primary, link-secondary, link-accent, link-info, link-neutral, link-success, link-warning, link-error, link-xs, link-sm, link-md, link-lg, link-xl, link-2xl, link-hover
Maskmask, mask-half-1, mask-half-2, mask-star, mask-star-2, mask-heart, mask-circle, mask-diamond, mask-squircle, mask-hexagon, mask-pentagon, mask-triangle
Swapswap, swap-rotate, swap-flip
Countdowncountdown, countdown-xs, countdown-sm, countdown-md, countdown-lg, countdown-xl
Marqueemarquee, marquee-track, marquee-fade, marquee-pause, marquee-reverse, marquee-vertical, marquee-slow, marquee-normal, marquee-fast
Carouselcarousel, carousel-item, carousel-vertical, carousel-center, carousel-end
Accordionaccordion, accordion-content, accordion-flush
Collapsiblecollapsible, collapsible-title, collapsible-content, collapsible-toggle, collapsible-arrow, is-collapsible-open, is-collapsible-close, collapsible-peek, collapsible-overlay, collapsible-group
Surfacesurface, surface-1, surface-2, surface-rounded, surface-xs, surface-sm, surface-md, surface-lg, surface-xl, surface-outline, surface-dashed

Vanilla JavaScript Helpers

Frutjam exports 8 optional DOM helpers from frutjam/js. The CSS components do not require a global initialization call. Use these functions when a page needs programmatic controls, searchable selection, or dynamic notifications.

ExportInitializer And Methods
createModalcreateModal(dialogElement) returns open(), close(), toggle(), isOpen().
createDrawercreateDrawer(dialogElement) uses the modal helper methods.
createCollapsiblecreateCollapsible(element) returns open(), close(), toggle(), isOpen().
createTooltipcreateTooltip(element) returns show(), hide(), toggle(), isOpen().
createTabscreateTabs(tabsElement, panelsElement) returns activate(index), next(), prev().
createToastManagercreateToastManager(containerElement) returns show(), success(), error(), warning(), info(), dismiss(element).
createCarouselcreateCarousel(element) returns goTo(index), next(), prev(), current(), count().
createComboboxcreateCombobox(element) returns open(), close(), toggle(), filter(query).

Toast Manager Options

For the Vanilla JS toast manager, show(message, { duration, type }) accepts duration (default 3000 milliseconds) and type (default an empty string). It returns the created alert element. success(message, options), error(message, options), warning(message, options), and info(message, options) specify the message type. Use dismiss(element) to remove a toast; duration: 0 disables timed removal.

JavaScript Helper Parameters

createTabs(tabsElement, panelsElement) accepts a tab list and an optional panel container. activate(index) uses a zero-based tab index. createCarousel(element).goTo(index) also uses a zero-based index and clamps it to available slides.

Combobox Selection Event

The combobox dispatches fj:select on its root when a selection is made. Listen on that root element; the custom event does not bubble. Its detail.value contains the selected item’s data-value or trimmed text.

React Hooks

React 18 or newer is required for the optional frutjam/react hooks. useToast().show() returns a toast ID; the Vanilla JS toast manager returns a DOM element. React toast options are duration (default 3000 milliseconds) and type (default an empty string).

HookPrimary Operation
useModal()ref, open(), close(), toggle(), isOpen().
useDrawer()Alias of useModal(). Returns ref, open(), close(), toggle(), isOpen().
useCollapsible()ref, open(), close(), toggle(), isOpen().
useTooltip()ref, show(), hide(), toggle(), isOpen().
useTabs(initialIndex = 0)active, activate(index), isActive(index), tablistProps, tabProps(index, count = 0), panelProps(index).
useToast()toasts, show(message, options), dismiss(id), success(), error(), warning(), info().
useCarousel()ref, current, goTo(index), next(), prev().
useCombobox({ items = [], filterFn } = {})open, value, query, filtered, activeIndex, select(item), containerProps, inputProps, listboxProps, optionProps(item, index).

Combobox Hook Filtering

useCombobox({ items, filterFn }) accepts an array of strings or objects with a label. A custom filterFn(items, query) can replace the default case-insensitive label filter.

All Frutjam UI Components

Inputs & Forms

Layout & Navigation

Feedback & Overlay

Data Display

Typography & Decoration

Cherry MCP Integration

Frutjam also has a separate Cherry MCP package for coding assistants. This integration supplies Frutjam component information to an MCP-capable editor. It is optional for building and running the UI.

{
  "mcpServers": {
    "frutjam": {
      "command": "npx",
      "args": ["-y", "frutjam-cherry"]
    }
  }
}

Alternatives & Related Resources

You Might Be Interested In:


Leave a Reply