alouette
alouette-responsive
Build adaptive layouts. Prefer Tailwind responsive variant classes (sm:, md:, lg:, xl:) for responsive styling — they work on web and native. alouette customizes the widths: sm 480, md 768, lg 1024, xl 1280. Fall back to SwitchBreakpointsUsingDisplayNone / SwitchBreakpointsUsingNull (and useCurrentBreakpointName) only when a class can't express the change — a different component tree per size, or unmounting a heavy off-screen variant.
alouette — Responsive design
Use Tailwind responsive variant classes (sm:, md:, lg:, xl:) for responsive styling. They are the default tool, work on web and native (NativeWind evaluates them at runtime), and need no extra component. alouette customizes the breakpoint widths: sm 480 · md 768 · lg 1024 · xl 1280 — note sm is 480px, not Tailwind's default 640.
Reach for SwitchBreakpoints* only when classes can't express the change: a genuinely different component tree per size, or unmounting a heavy off-screen variant.
Setup
import { View } from "alouette";
<View className="flex-col md:flex-row gap-m">…</View>;Core Patterns
Responsive utility classes (preferred)
<View className="p-m lg:p-xl" />
<Text className="text-base md:text-lg" />
<View className="flex-col md:flex-row" />Stack on narrow screens, switch to a row at md (768px) and up.
Switch whole subtrees when classes aren't enough
When a breakpoint needs different components (not just different classes), use SwitchBreakpoints. UsingDisplayNone keeps every slot mounted and toggles visibility (SSR-friendly on web); UsingNull mounts only the matching slot — use it to keep heavy off-screen variants unmounted. The base slot is required.
import { SwitchBreakpointsUsingNull } from "alouette";
<SwitchBreakpointsUsingNull base={<MobileNav />} large={<DesktopSidebar />} />;Read the current breakpoint in JS
import { useCurrentBreakpointName } from "alouette";
const bp = useCurrentBreakpointName(); // "base" | "small" | "medium" | "large" | "wide"Common Mistakes
HIGH Using SwitchBreakpoints where a responsive class would do
Wrong:
<SwitchBreakpointsUsingNull
base={<View className="flex-col" />}
medium={<View className="flex-row" />}
/>Correct:
<View className="flex-col md:flex-row" />Responsive variant classes are the default; they avoid mounting multiple subtrees and work on web + native. Use SwitchBreakpoints* only when the variants are genuinely different components or the off-screen one must be unmounted.
Source: packages/alouette/src/windowSize/SwitchBreakpoints.tsx
MEDIUM Assuming Tailwind's default breakpoint widths
Wrong:
// expecting sm: to start at 640px
<View className="sm:flex-row" />Correct:
// alouette sm: starts at 480px; md 768 / lg 1024 / xl 1280
<View className="md:flex-row" />alouette overrides the breakpoint widths, so picking a prefix by Tailwind's defaults shifts the layout boundary.
Source: packages/alouette/src/config/Breakpoints.ts
MEDIUM Building responsive class names dynamically
Wrong:
const cls = `${bp}:flex-row`;
<View className={cls} />;Correct:
<View className="md:flex-row" />Tailwind v4 only emits classes it sees as literal strings, so a runtime-built ${bp}:flex-row is never generated.
Source: packages/alouette/src/windowSize/SwitchBreakpoints.tsx
MEDIUM SwitchBreakpoints without a base slot
Wrong:
<SwitchBreakpointsUsingNull medium={<Wide />} />Correct:
<SwitchBreakpointsUsingNull base={<Narrow />} medium={<Wide />} />When you do use SwitchBreakpoints, base is required — it is the fallback below the smallest defined breakpoint. Omitting it is a type error.
Source: packages/alouette/src/windowSize/SwitchBreakpoints.tsx