Reacting to a breakpoint

matchMedia()

Baseline widely available
  • Chrome9
  • Edge12
  • Firefox6
  • Safari5.1

Features it needs

These libraries wrap one method. matchMedia() takes the same query string a stylesheet would, reports whether it matches now, and fires an event when that changes, with no resize listener and no width arithmetic. Most uses of them are styling rather than logic, and a media or container query in CSS handles those without JavaScript running at all.

When this applies

JavaScript needs to know whether a media query currently matches.

The native approach

const wide = matchMedia("(min-width: 48rem)");

function apply(event) {
  // Same shape for the initial read and every later change.
  setColumns(event.matches ? 3 : 1);
}

apply(wide);
wide.addEventListener("change", apply);

MDN reference

When the dependency is still right

An answer that always says "the platform covers it" is worse than no answer. These are the cases where this one does not hold.

  • You server-render and need the first paint to be right. matchMedia does not exist on the server and the client's first read happens after hydration, so a wrong first frame or a mismatch warning is the failure mode these libraries put real work into avoiding.
  • You are changing appearance rather than behaviour. A media query or a container query does that in CSS, which is fewer moving parts than either the library or this API.
  • You query an element's size rather than the viewport's. matchMedia only answers about the viewport and the device, so a component that responds to its own box needs a container query or ResizeObserver.
  • The library's other features are in use, such as react-responsive's device-property shorthands or its context-based overriding for tests.

Signs it was hand-rolled

No package is involved in any of these, so nothing would match in a package.json. If the code looks like one of them, this rule applies anyway, and the conditions above still decide.

  • a resize listener comparing window.innerWidth against a breakpoint number kept in JavaScript
  • an isMobile flag held in state and recomputed from innerWidth inside a debounced resize handler

Packages this covers