mrkeyoor.com_
Sat 08 Aug 22:50 UTC
npmWeb Frontendupdated 08 Aug 2026

css-mediaquery

css-mediaquery is a dependency-free CommonJS module with two functions: parse() converts a CSS Media Queries Level 3-style string into a small array AST, and match() evaluates that string against a JavaScript object representing a device or browser state. It handles comma-separated alternatives, not and only modifiers, min/max features, orientation, dimensions, resolution, aspect ratios, and several legacy device features. It is often used in server rendering or tests where window.matchMedia is unavailable, but it is not a browser engine and its unit model is fixed in code.

Verdict

css-mediaquery remains useful as a frozen compatibility layer for simple SSR and tests. Do not treat its answer as browser truth for modern queries, relative units, calculated values, or exact physical-unit conversion.

API stability4/5The package has exposed only parse and match since its initial releases, and the AST shape documented in the README still matches source: inverse, type, and expression objects with modifier, feature, and value. That tiny surface makes existing callers predictable. The score is not five because it is version 0.1.2, malformed inputs can expose implementation errors, values use undocumented coercions, and several observable bugs would require behavior changes if maintainers ever merged the waiting fixes.
Docs3/5The README clearly documents installation, both exports, a full match example, the required concrete type field, the parse AST, comma-era CSS recommendations, supported feature intent, and common-unit conversion. The source is short enough to audit. Documentation does not disclose the fixed 16px em/rem model, incorrect point and pica math, falsy-zero behavior, repeated parsing, lack of modern range syntax, unknown-feature equality, thrown errors from match, or the lack of AST serialization and matching.
Maintenance1/5Version 0.1.2 was published in January 2014. The next code commits from that same month were never released, and the only later default-branch change corrected the package license identifier in September 2024. An open 2025 issue asks for a release containing even that metadata fix. Sixteen open issues and pull requests include unit bugs, zero matching, calc crashes, modern features, AST matching, and fixes dating back to 2014, showing a long maintenance backlog.
Ecosystem3/5The npm package recorded 3,297,302 downloads in the measured week, has 116 GitHub stars, and is useful to older SSR and testing dependency trees because it has no runtime dependencies. Its AST is package-specific rather than part of PostCSS or another shared parser ecosystem, it offers no types or plugins, and direct development activity is very low. Most of its ecosystem value is compatibility with existing packages that already chose its simple match function.

Use it if

  • You maintain server-side rendering or tests already depending on this package's match(query, values) contract
  • Your queries stay within classic Media Queries Level 3 syntax and use simple numeric values
  • You need a tiny parser AST for inspection rather than a full CSS stylesheet parser
  • You can supply an explicit synthetic device state including a media type for every match
Skip it if

Setup reality

npm install css-mediaquery is the entire installation. There are no runtime dependencies, peers, native builds, credentials, or config files. Require the module and call either match(query, values) or parse(query). The work is in constructing values correctly. The README says type is required and cannot be all; use screen, print, or the concrete medium you are simulating. Dimension and resolution values may be numbers or unit-bearing strings, but the conversion model is not tied to a DOM, root font size, zoom, viewport, or device. em and rem always mean 16px. Width-like values recognize px, em, rem, cm, mm, in, pt, and pc, while resolution recognizes dpi, dpcm, and dppx. Aspect ratios can be decimals or strings such as 16/9. Missing or falsy feature values fail a positive expression, which means zero is mishandled and has an open fix pull request. parse() throws SyntaxError for malformed query structure; match() calls parse internally, so malformed user input also throws rather than returning false. Unknown feature names can enter the AST and fall through to strict value equality, which can look like support without browser semantics. The AST is descriptive only: there is no serializer or public match-from-AST function. For SSR, keep the server's assumed viewport policy explicit and expect hydration differences if the actual client differs. This package cannot observe changes, attach listeners, or replace the live window.matchMedia object on its own.

Patterns

Match a minimum viewport widthmatch-min-width

const mediaQuery = require('css-mediaquery');

const matches = mediaQuery.match('screen and (min-width: 40em)', {
  type: 'screen',
  width: '1024px',
});

The package always converts em and rem using 16px, regardless of root font size, browser zoom, or supplied values.

Match any comma-separated querymatch-query-list

const matches = mediaQuery.match(
  'screen and (min-width: 900px), print',
  { type: 'print', width: '800px' }
);
// true

A comma is treated as logical OR by parsing separate query objects and returning true when any one matches.

Match screen orientationmatch-orientation

mediaQuery.match('screen and (orientation: landscape)', {
  type: 'screen',
  orientation: 'landscape',
});

The library compares the provided orientation string case-insensitively; it does not derive orientation from width and height.

Compare resolution across unitsmatch-resolution

mediaQuery.match('(min-resolution: 2dppx)', {
  type: 'screen',
  resolution: '192dpi',
});
// true

dppx is converted using 96 dpi and dpcm through the source's conversion formula. Pass units explicitly for readable fixtures.

Match an aspect ratiomatch-aspect-ratio

mediaQuery.match('(min-aspect-ratio: 16/9)', {
  type: 'screen',
  'aspect-ratio': '1.8',
});
// true

Feature keys with hyphens must be quoted in object literals. The package converts ratio strings to decimal numbers.

Evaluate a negated media typematch-negated-query

mediaQuery.match('not print and (color)', {
  type: 'screen',
  color: 8,
});
// true

not inverts the whole query result. The only modifier is parsed but otherwise ignored, matching its legacy compatibility purpose.

Inspect a media query as an ASTparse-query-ast

const ast = mediaQuery.parse(
  'screen and (min-width: 48em) and (orientation: landscape)'
);

for (const expression of ast[0].expressions) {
  console.log(expression.modifier, expression.feature, expression.value);
}

The parser preserves values as strings and does not expose a serializer. match() cannot accept this AST, only the original string.

Handle invalid query syntaxcatch-invalid-query

function safeMatch(query, values) {
  try {
    return mediaQuery.match(query, values);
  } catch (error) {
    if (error instanceof SyntaxError) return false;
    throw error;
  }
}

match reparses on every call and can throw SyntaxError. Conversion bugs can also throw other errors, so only swallow the syntax case you intend.

Build a minimal matchMedia result for SSRcreate-ssr-matchmedia

function ssrMatchMedia(query) {
  return {
    matches: mediaQuery.match(query, { type: 'screen', width: '1024px' }),
    media: query,
    onchange: null,
    addListener() {},
    removeListener() {},
    addEventListener() {},
    removeEventListener() {},
    dispatchEvent() { return false; },
  };
}

This is a static server assumption, not a live MediaQueryList. Client hydration can disagree when the actual viewport differs.

Match legacy device features explicitlysupply-device-features

mediaQuery.match(
  'screen and (min-device-width: 768px) and (min-color: 8)',
  {
    type: 'screen',
    'device-width': '1024px',
    color: 24,
  }
);

The values object is not inferred from Node or a browser. Every referenced feature must be present and truthy.

Account for falsy zero valuesavoid-zero-value-bug

const values = {
  type: 'screen',
  monochrome: String(device.monochromeDepth),
};
const matches = mediaQuery.match('(monochrome: 0)', values);

A numeric 0 is treated as missing by the source's if (!value) check. A string can bypass that check, but test semantics carefully because an open pull request targets this bug.

Memoize repeated fixed-state matches outside the packagecache-query-result

const cache = new Map();
function matchAtDesktop(query) {
  if (!cache.has(query)) {
    cache.set(query, mediaQuery.match(query, {
      type: 'screen', width: '1280px'
    }));
  }
  return cache.get(query);
}

The public match function parses the query each time. Cache only when both query and simulated device values are truly fixed.

Alternatives

PackageRegistryPick it when
media-query-parsernpmYou want a dedicated parser for media-query text and do not need this package's device-state matcher
postcss-media-query-parsernpmYou are already in a PostCSS workflow and need a media-query AST for transforms
matchmediaquerynpmYou primarily need server-side query matching and prefer a package focused on that operation