Skip to content

Responsive Media ​

Reactive boolean state from CSS media queries and element dimensions for Vanilla JS, Vue 3, Nuxt and React 19+ — AND/OR conditions, container queries, ordered breakpoint helpers, rich subscription API, CSS vars sync, SSR-safe, typed from your own config — with no required peer dependencies.

Features ​

  • Framework-agnostic core — ReactiveResponsiveState and ContainerState work with Vanilla JS, any signals library, or any framework; Vue and React are optional peer dependencies
  • Viewport breakpoints — backed by window.matchMedia; conditions combined with AND (flat array) or OR (nested array); raw media type support for print, screen, etc.
  • Full condition vocabulary — min/max-width, min/max-height, orientation, aspect-ratio, prefers-color-scheme, prefers-reduced-motion, prefers-contrast, hover, pointer, forced-colors, resolution, display-mode, and raw
  • Container queries (JS-side) — ContainerState tracks an element's dimensions via ResizeObserver and evaluates breakpoint conditions in JavaScript; identical API to viewport state
  • Rich subscription API — subscribe, on, onEnter, onLeave, once, onNextChange, onBreakpointChange, waitFor; optional debounce for subscribe; per-key listeners are never debounced
  • Ordered breakpoint helpers — current, isAbove(), isBelow(), between() for semantic viewport comparisons; order derived from config key insertion or explicit order option
  • Utilities — syncCSSVars (CSS custom properties), emitDOMEvents (DOM CustomEvents), toSignal (any signals library — Preact, Angular, SolidJS, Vue), match (pick value by first active breakpoint), subscribeMediaQuery (raw single query)
  • Vue 3 adapter — useResponsive, useBreakpoints, useMediaQuery, useContainerState; fully reactive in templates and computed; ResponsivePlugin for global config
  • React 19+ adapter — same four hooks; useSyncExternalStore for safe concurrent rendering; SSR-safe (false on server)
  • Nuxt module — responsive-media/nuxt: breakpoints in nuxt.config.ts, auto-imported composables typed from your breakpoints, an app plugin, and ssrState for what the server renders
  • Hydration-safe SSR — ssrState gives the server a layout, deferred hydration removes the mismatch warning, and request hints (cookie, user-agent) let the server render for the visitor's own device
  • More hooks — useResponsiveValue (a value per breakpoint), useUserPreferences (dark mode, reduced motion, …), useViewportSize (the window size as numbers), and a reactive query for useMediaQuery
  • CSS from the same config — SCSS module, @custom-media and Tailwind screens generated from your breakpoints
  • Test helpers — responsive-media/testing is a controllable matchMedia for Vitest and Jest
  • Typed from your config — defineResponsive(config) (Vue and React) infers the state and the breakpoint keys, so a typo is a compile error; useContainerState infers its keys the same way
  • Presets — TailwindPreset, BootstrapPreset, AccessibilityPreset out of the box; user-preference queries (dark, reducedMotion, highContrast, print, …)
  • SSR-safe — all APIs check for window / matchMedia / ResizeObserver before use; hydrate() prevents layout shift on the client
  • TypeScript — full generics; ConfigToState<T> infers a boolean-state type from any config object