Breakpoints
FrontAlign uses a mobile-first breakpoint system: every utility you write without a prefix applies to all screen sizes, and each breakpoint prefix (md:, lg:, xl:, etc.) turns that utility on starting at that width and up. Nothing below the breakpoint is affected by it.
<div class="is-hidden md:block lg:flex">
Here, is-hidden is the base style (display: none) and applies on every screen by default. md:block overrides display starting at the md width, switching the element on. lg:flex overrides display again starting at the lg width, switching it to a flex container. Below md, only is-hidden is active — that's what "below a breakpoint" means: the styles tied to a larger breakpoint simply haven't kicked in yet, so the element stays hidden.
Under the hood, each breakpoint compiles to a min-width media query, and the compiler only outputs the queries that are actually used by classes it finds while scanning your project.
Default Breakpoints
FrontAlign ships with the following scale out of the box:
export const DEFAULT_BREAKPOINTS = {
sm: "640px",
md: "864px",
lg: "1120px",
xl: "1408px",
"2xl": "1792px",
};
| Key | Value | Turns on at |
|---|---|---|
sm | 640px | Large phones in landscape and small tablets |
md | 864px | Tablets and split-screen/multitasking windows |
lg | 1120px | Small laptops and tablets in landscape |
xl | 1408px | Standard laptop and desktop viewports |
2xl | 1792px | Large desktop monitors and wide displays |
These five tiers are enough to cover the vast majority of layouts without introducing so many breakpoints that maintaining responsive variants becomes a burden.
Customizing Breakpoints
Breakpoints are part of your design tokens, so they live inside theme, right alongside colors, fonts, and spacing — not as a separate top-level key.
export default {
jit: {
scan: ['./app', './components', './pages']
},
theme: {
primary: '#2563eb',
body: '#ffffff',
bodyText: '#111827',
font: 'Inter, sans-serif',
breakpoints: {
sm: '640px',
md: '864px',
lg: '1120px',
xl: '1408px',
'2xl': '1792px'
}
}
}
The Compiler Engine reads theme.breakpoints the same way it reads the rest of theme, and generates the matching min-width media queries into fa.build.css.
Generated Output
:root {
--body: #ffffff;
--body-text: #111827;
--primary: #2563eb;
--font: Inter, sans-serif;
}
@media (min-width: 640px) {
/* sm utilities */
}
@media (min-width: 864px) {
/* md utilities */
}
@media (min-width: 1120px) {
/* lg utilities */
}
@media (min-width: 1408px) {
/* xl utilities */
}
@media (min-width: 1792px) {
/* 2xl utilities */
}
/* ... FrontAlign base styles and active utility classes ... */
Only the tiers actually used by scanned classes (for example md:hero-card or lg:hidden) are extracted into the final output — the same JIT extraction behavior already applied to base utilities and custom classes.
Partial Overrides
You don't have to redefine every tier. Any key left out of theme.breakpoints falls back to DEFAULT_BREAKPOINTS:
export default {
theme: {
breakpoints: {
lg: '1024px',
xl: '1280px'
}
}
}
In this example, sm, md, and 2xl keep their default values (640px, 864px, 1792px), while lg and xl use the overridden values.
Rebuilds in Watch Mode
Like every other key inside theme, changing breakpoints while npx frontalign dev is running triggers a rebuild of fa.build.css with the new media query values — no restart required.