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",
};
KeyValueTurns on at
sm640pxLarge phones in landscape and small tablets
md864pxTablets and split-screen/multitasking windows
lg1120pxSmall laptops and tablets in landscape
xl1408pxStandard laptop and desktop viewports
2xl1792pxLarge 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.

FrontAlign