Coming from Tailwind
Most Beam utilities look exactly like Tailwind — flex, gap-4, px-6, rounded-md, justify-between. A handful of layout names differ because Beam uses the underlying CSS property vocabulary instead of Tailwind shorthand. This page is the complete map.
Naming differences
These are the utilities that look different. Everything else in Beam is the same class name you already know.
| Tailwind | Beam | CSS property |
|---|---|---|
flex-col | direction-column | flex-direction: column |
flex-row | direction-row | flex-direction: row |
flex-wrap | wrap | flex-wrap: wrap |
flex-nowrap | nowrap | flex-wrap: nowrap |
items-center | align-center | align-items: center |
items-start | align-start | align-items: flex-start |
items-end | align-end | align-items: flex-end |
items-stretch | align-stretch | align-items: stretch |
items-baseline | align-baseline | align-items: baseline |
place-items-center | place-center | place-items: center |
grid-cols-3 | cols-3 | grid-template-columns: repeat(3,1fr) |
grid-cols-[200px_1fr] | cols-[200px_1fr] | grid-template-columns: 200px 1fr |
grid-rows-2 | rows-2 | grid-template-rows: repeat(2,1fr) |
The logic: Tailwind uses compound shorthand (flex-col, items-*). Beam uses the CSS property name directly (direction-*, align-*). Once you know the pattern you can usually guess the Beam name from the CSS spec.
What stays the same
The vast majority of your Tailwind muscle memory transfers directly:
| Category | Examples (identical in both) |
|---|---|
| Display | flex · grid · block · inline-block · hidden · inline-flex · inline-grid |
| Justify content | justify-center · justify-between · justify-start · justify-end · justify-around · justify-evenly |
| Spacing | p-4 · px-6 · py-2 · pt-8 · gap-4 · gap-x-2 · m-auto · mx-4 |
| Sizing | w-full · h-screen · max-w-* · min-h-* |
| Typography | font-bold · font-semibold · leading-* · tracking-* · uppercase · text-center |
| Border | border · border-2 · border-solid · border-dashed · rounded-md · rounded-full |
| Position | relative · absolute · fixed · sticky · top-* · inset-* |
| Effects | opacity-75 · scale-105 · cursor-pointer · overflow-hidden · z-10 |
Colors: semantic tokens instead of scales
Tailwind uses numeric scales (bg-blue-500). Beam uses semantic design tokens from your config — names like bg-surface, text-accent, border-line. You define the token map once and reference meaning, not a hardcoded shade.
<!-- Tailwind: hardcoded scale -->
<div class="bg-white text-gray-900 border-gray-200">
<!-- Beam: semantic tokens from your beam.config.ts -->
<div class="bg-surface text-fg border-line">This means a dark-mode toggle or rebrand changes one token, not every class in your codebase.
What you gain over Tailwind
1. Variant grouping
Factor a repeated variant prefix out of a class string. Both forms produce identical atomic CSS — the group is author-time sugar only.
<!-- Tailwind: prefix repeats on every utility -->
<button class="rounded-md px-4 py-2 bg-blue-500 text-white
hover:bg-blue-700 hover:shadow-lg hover:scale-105">
<!-- Beam: prefix lives once, group expands at build time -->
<button class="rounded-md px-4 py-2 bg-accent text-on-accent
hover:(bg-accent+12 shadow-lg scale-105)">Variants stack — tablet:hover:(bg-surface scale-105) means "at tablet breakpoint AND on hover".
2. Utility grouping
Related declarations stay together without repeating the property family prefix.
<!-- Tailwind -->
<article class="p-4 pt-6 pb-6 px-8">
<!-- Beam -->
<article class="padding:(4 top:6 bottom:6 x:8)">3. Color algebra
Lighten, darken, or set alpha on any token inline — no intermediate Tailwind arbitrary value needed.
bg-accent+12 → color-mix(in oklab, var(--color-accent), white 12%)
bg-accent-20 → color-mix(in oklab, var(--color-accent), black 20%)
bg-accent/50 → color-mix(in oklab, var(--color-accent) 50%, transparent)4. Dynamic CSS custom properties
Bind a CSS variable at runtime with a stable atomic class — no JIT purge issues, no safelisting.
// Tailwind: dynamic class string, needs safelisting or JIT
<div style={{ width: `${pct}%` }}>
// Beam: one stable class, value is driven by the CSS variable
<div className="w-(--progress)" style={{ '--progress': `${pct}%` }}>Side by side: a real component
<!-- Tailwind -->
<div class="flex flex-col items-center gap-4 p-6
bg-white rounded-lg border border-gray-200
hover:shadow-lg hover:border-blue-200">
<h2 class="text-xl font-bold text-gray-900">Title</h2>
<p class="text-sm text-gray-500">Description</p>
</div>
<!-- Beam -->
<div class="flex direction-column align-center gap-4 p-6
bg-surface rounded-lg border border-line
hover:(shadow-lg border-accent/20)">
<h2 class="text-xl font-bold text-fg">Title</h2>
<p class="text-sm text-muted">Description</p>
</div>Tip: recreate Tailwind names as shortcuts
If you want to keep writing flex-col and items-center during a migration, define them as shortcuts in your config:
import { defineConfig } from 'beamcss'
export default defineConfig({
shortcuts: {
'flex-col': 'direction-column',
'flex-row': 'direction-row',
'items-center': 'align-center',
'items-start': 'align-start',
'items-end': 'align-end',
},
})See Configuration for the full shortcuts and recipes API.