Tailwind Preset

How Byteion plugs into Tailwind — the v3 preset, the v4 CSS-first entry, and when to use each.

Overview

@byteion/core is the bridge between Byteion's token system and Tailwind utility classes. The bridge takes a different shape in each Tailwind version:

Without one of these bridges, Byteion-specific utilities such as bg-primary, shadow-card, z-modal, and animate-fade-in will not be generated from the Byteion token system.

Which setup should I use?

  • Use Tailwind v4 CSS-first for new projects. It is simpler (one CSS import, no JS config) and is the recommended setup for all new apps.
  • Use Tailwind v3 preset for existing Tailwind v3 apps, older Laravel / Vite stacks, or projects that cannot upgrade yet.
  • Do not mix the v3 preset and v4 CSS-first setup in the same app — they configure the same tokens through different mechanisms and will conflict.
  • Keep app-specific extensions separate from Byteion's core token contract. Use @theme (v4) or theme.extend (v3) for app-only additions; do not modify Byteion's tokens directly.

Tailwind v4 (CSS-first)

v4 configures Tailwind in CSS rather than JS. Place this in your main CSS entry — for example src/app.css, resources/css/app.css, or app/globals.css:

@import "tailwindcss";
@import "@byteion/core";

/* Optional brand themes */
@import "@byteion/core/theme/themes/acme.css";
@import "@byteion/core/theme/themes/midnight.css";

/* Tell Tailwind to scan runtime-built class strings */
@source "../node_modules/@byteion/js/src";
@source "../node_modules/@byteion/react/dist";   /* if React */
@source "../node_modules/@byteion/vue/dist";     /* if Vue */

Adjust the @source relative paths based on where your CSS file lives. You need @source when class names live inside distributed Byteion runtime / framework packages that are not in your source tree.

The single @import "@byteion/core" expands to:

  1. Primitive palette (--palette-* HSL triplets)
  2. Semantic theme layer (--background, --primary, …)
  3. v4 @theme inline adapter that maps both into v4 namespaces
  4. Dark-mode @custom-variant dark (fires under .dark AND [data-theme="dark"])
  5. Named z-index utilities (z-modal, z-tooltip, …)
  6. v3-compatible base reset (border-color from --border)
  7. Named border widths (border-sm, border-md, border-lg) and decorative backgrounds

Tailwind v3 (preset)

In v3 the bridge is a Tailwind preset (packages/core/tailwind.preset.cjs). Reference it from your tailwind.config.js:

import preset from '@byteion/core/preset';

/** @type {import('tailwindcss').Config} */
export default {
  presets: [preset],
  content: [
    './src/**/*.{html,js,jsx,ts,tsx,vue}',
    './node_modules/@byteion/js/src/**/*.js',           // always
    './node_modules/@byteion/react/dist/**/*.{js,cjs}', // if React
    './node_modules/@byteion/vue/dist/**/*.{js,cjs}',   // if Vue
  ],
  darkMode: ['class', '[data-theme="dark"]'],
};

The preset already sets darkMode: ['class', '[data-theme="dark"]'] so dark: variants fire under both .dark and [data-theme="dark"] selectors. You do not need to redeclare it unless you want to override.

For CommonJS environments (older Next.js, Laravel Mix):

const preset = require('@byteion/core/preset');

module.exports = {
  presets: [preset],
  content: ['./src/**/*.{html,js,jsx,tsx,vue}'],
  darkMode: ['class', '[data-theme="dark"]'],
};

Your CSS entry must load the token files that the preset's utility classes reference at runtime:

@import "@byteion/core/theme/generated/tokens.css";
@import "@byteion/core/theme/variables.css";
@import "@byteion/core/theme/themes/acme.css";  /* optional brand */

@tailwind base;
@tailwind components;
@tailwind utilities;

Generated utilities reference CSS variables at runtime, so the variables must be loaded in the browser before components render. Load Byteion defaults before @tailwind base and place app-specific overrides after Byteion defaults.

What gets configured

CategoryWhat gets added
colorsSemantic aliases (bg-background, text-foreground, border-border) and full palette scales (primary-50 through primary-950)
boxShadow25 named shadows — card, dropdown, modal, popover, button, field, glow, dark variants
borderRadiusComponent radii — button, input, badge, card, panel, overlay
borderWidthSemantic widths — sm (1px), md (2px)
zIndexLayer stack — backdrop, dropdown, overlay, modal, toast, tooltip
keyframes / animation16 named animations with preset durations and easings
fontFamilyInter sans-serif with system fallbacks
fontSize / fontWeight9-step type scale (xs through 5xl) with paired line heights, 4 weights
transitionDuration / transitionTimingFunction3 durations (fast, normal, slow) and 3 easings (default, in, out)
backgroundImage / backgroundSizeDecorative gradients (shimmer, stripes) used by skeleton / progress components
spacingInset, stack, and surface scale mapped to p-*, gap-*, space-y-*

Extending Byteion

v3 — extend the preset in tailwind.config.js:

import preset from '@byteion/core/preset';

export default {
  presets: [preset],
  theme: {
    extend: {
      colors: { brand: { 50: '#faf5ff', 500: '#8b5cf6' } },
    },
  },
};

v4 — extend with @theme in your CSS:

@import "tailwindcss";
@import "@byteion/core";

@theme {
  --color-brand-50:  oklch(0.97 0.02 285);
  --color-brand-500: oklch(0.62 0.21 285);
}

Use extension for true app-specific additions. Do not use it to bypass Byteion's semantic token contract — prefer CSS variables for anything that should be themeable across modes or brands.

Common mistakes

  • Mixing v3 preset and v4 CSS-first in the same project. Use one or the other.
  • Forgetting @source paths in v4 when using @byteion/react, @byteion/vue, or @byteion/js — classes in those packages will not be scanned.
  • Forgetting content paths in v3 — Byteion framework classes will be purged.
  • Importing brand overrides before Byteion defaults — overrides must come after variables.css to take precedence.
  • Using @byteion/core/preset in a Tailwind v4 app — v4 does not use JavaScript presets.
  • Hardcoding colors (bg-white, text-gray-900) instead of using semantic token utilities (bg-background, text-foreground).
  • Expecting dark: variants to work without class-based dark mode configured — ensure darkMode is set.

Verification checklist

After configuring the preset, verify each of these:

  • bg-primary renders with the brand color.
  • text-primary-foreground has correct contrast on bg-primary.
  • shadow-card and z-modal generate and apply correctly.
  • Dark mode works — toggle .dark on <html> and verify all surfaces swap.
  • React / Vue component classes are included by @source (v4) or content (v3).
  • Production build does not purge Byteion classes — check the output CSS.
  • Brand theme imports override the expected variables — test with a non-default theme.

Developer tips

• v4: @import "@byteion/core" is the recommended setup for new projects. Single import, no JS config, full token setup. • v3: use the preset and load runtime variables in your CSS entry. The preset maps tokens to utilities; variables.css provides the runtime values. • Both versions share the same semantic variables. Brand themes (themes/acme.css) work identically in v3 and v4. • Do not add a --color- prefix to semantic variables. Use --primary, --background, --border — the Tailwind preset wraps them with hsl(var(--name) / <alpha-value>). • Use Tailwind extension for app-specific additions. Do not bypass Byteion's semantic token contract.

Unlock Premium Patterns

Get access to copy-paste ready Pro blocks, SaaS templates, and advanced component patterns.

Explore Pro Components