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:
v4 — CSS-first
@import "@byteion/core" wires everything. No JS preset.
v3 — JS preset
presets: [preset] in tailwind.config.js.
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) ortheme.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:
- Primitive palette (
--palette-*HSL triplets) - Semantic theme layer (
--background,--primary, …) - v4
@theme inlineadapter that maps both into v4 namespaces - Dark-mode
@custom-variant dark(fires under.darkAND[data-theme="dark"]) - Named z-index utilities (
z-modal,z-tooltip, …) - v3-compatible base reset (border-color from
--border) - 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
| Category | What gets added |
|---|---|
| colors | Semantic aliases (bg-background, text-foreground, border-border) and full palette scales (primary-50 through primary-950) |
| boxShadow | 25 named shadows — card, dropdown, modal, popover, button, field, glow, dark variants |
| borderRadius | Component radii — button, input, badge, card, panel, overlay |
| borderWidth | Semantic widths — sm (1px), md (2px) |
| zIndex | Layer stack — backdrop, dropdown, overlay, modal, toast, tooltip |
| keyframes / animation | 16 named animations with preset durations and easings |
| fontFamily | Inter sans-serif with system fallbacks |
| fontSize / fontWeight | 9-step type scale (xs through 5xl) with paired line heights, 4 weights |
| transitionDuration / transitionTimingFunction | 3 durations (fast, normal, slow) and 3 easings (default, in, out) |
| backgroundImage / backgroundSize | Decorative gradients (shimmer, stripes) used by skeleton / progress components |
| spacing | Inset, 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
@sourcepaths in v4 when using@byteion/react,@byteion/vue, or@byteion/js— classes in those packages will not be scanned. - Forgetting
contentpaths in v3 — Byteion framework classes will be purged. - Importing brand overrides before Byteion defaults — overrides must come after
variables.cssto take precedence. - Using
@byteion/core/presetin 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 — ensuredarkModeis set.
Verification checklist
After configuring the preset, verify each of these:
bg-primaryrenders with the brand color.text-primary-foregroundhas correct contrast onbg-primary.shadow-cardandz-modalgenerate and apply correctly.- Dark mode works — toggle
.darkon<html>and verify all surfaces swap. - React / Vue component classes are included by
@source(v4) orcontent(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
@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.Related
- Installation — full v3 / v4 / CDN install matrix
- CSS Variables — the runtime token layer
- Quick Start — end-to-end project setup, both versions
- Theming Guide — override brand colors via semantic variables
- Dark Mode — class-based toggling and system preference fallback
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced component patterns.
Explore Pro Components