
Research
/Security News
77 Firefox Extensions Linked to Crypto Wallet and Credential Theft
Socket uncovered 77 linked Firefox extensions, including 40 that steal wallet secrets or credentials and 37 deceptive sports-score shells.
@solid-primitives/media
Advanced tools
Collection of reactive primitives to deal with media queries.
makeMediaQueryListener - Listen for changes to provided Media Query.createMediaQuery - Creates a very simple and straightforward media query monitor.createBreakpoints - Creates a multi-breakpoint monitor to make responsive components easily.createPrefersDark - Provides a signal indicating if the user has requested dark color theme.npm install @solid-primitives/media
# or
yarn add @solid-primitives/media
# or
pnpm add @solid-primitives/media
Requires Solid.js v2.0 (beta.7+)
makeMediaQueryListenerAttaches a MediaQuery listener to window, listeneing to changes to provided query
import { makeMediaQueryListener } from "@solid-primitives/media";
const clear = makeMediaQueryListener("(max-width: 767px)", e => {
console.log(e.matches);
});
// remove listeners (will happen also on cleanup)
clear();
createMediaQueryCreates a very simple and straightforward media query monitor.
import { createMediaQuery } from "@solid-primitives/media";
const isSmall = createMediaQuery("(max-width: 767px)");
console.log(isSmall());
createMediaQuery accepts a serverFallback argument — value that should be returned on the server — defaults to false.
const isSmall = createMediaQuery("(max-width: 767px)", true);
// will return true on the server and during hydration on the client
console.log(isSmall());
createBreakpointsCreates a multi-breakpoint monitor to make responsive components easily.
import { createBreakpoints } from "@solid-primitives/media";
const breakpoints = {
sm: "640px",
lg: "1024px",
xl: "1280px",
};
const Example: Component = () => {
const matches = createBreakpoints(breakpoints);
createEffect(
() => [matches.sm, matches.lg, matches.xl],
([sm, lg, xl]) => {
console.log(sm); // true when screen width >= 640px
console.log(lg); // true when screen width >= 1024px
console.log(xl); // true when screen width >= 1280px
},
);
return (
<div
class={[
"text-tiny flex-column flex", // tiny text with flex column layout
matches.sm && "text-small", // small text with flex column layout
matches.lg && "flex-row text-base", // base text with flex row layout
matches.xl && "text-huge", // huge text with flex row layout
]}
>
<Switch fallback={<div>Smallest</div>}>
<Match when={matches.xl}>Extra Large</Match>
<Match when={matches.lg}>Large</Match>
<Match when={matches.sm}>Small</Match>
{/*
Instead of fallback, you can also use `!matches.sm`
<Match when={!matches.sm}>Smallest</Match>
*/}
</Switch>
</div>
);
};
.toString methodAs a convenience feature, the return value of createBreakpoints also contains a non-enumerable .key property that will return the last matching breakpoint id to allow using it as an object key:
import { createBreakpoints } from "@solid-primitives/media";
const breakpoints = {
sm: "640px",
lg: "1024px",
xl: "1280px",
};
const matches = createBreakpoints(breakpoints);
const moduleSize = () =>
({
sm: 2,
lg: 4,
xl: 6,
})[matches.key];
This can be very helpful for things like the mapHeight option in createMasonry.
Warning for this feature to work, the breakpoints needs to be ordered from small to large. If you cannot ensure this, use the
sortBreakpointshelper.
sortBreakpoints helperIf you cannot rely on the order of the breakpoints from smallest to largest, this small helper fixes it for you:
// unfortunately in the wrong order:
const breakpoints = {
xl: "1280px",
lg: "1024px",
sm: "640px",
};
const matches = createBreakpoints(sortBreakpoints(breakpoints));
const moduleSize = () =>
({
sm: 2,
lg: 4,
xl: 6,
})[matches.key];
createPrefersDarkProvides a signal indicating if the user has requested dark color theme. The setting is being watched with a Media Query.
import { createPrefersDark } from "@solid-primitives/media";
const prefersDark = createPrefersDark();
createEffect(prefersDark, dark => console.log("prefers dark:", dark));
createPrefersDark accepts a serverFallback argument — value that should be returned on the server — defaults to false.
const prefersDark = createPrefersDark(true);
// will return true on the server and during hydration on the client
prefersDark();
usePrefersDarkThis primitive provides a singleton root variant that will reuse the same signal and media query across the whole application.
import { usePrefersDark } from "@solid-primitives/media";
const prefersDark = usePrefersDark();
createEffect(prefersDark, dark => console.log("prefers dark:", dark));
Note:
usePrefersDarkwill deopt tocreatePrefersDarkif used during hydration. (see issue #310)
addListenerDue to older versions of mobile Safari on iOS 13 not supporting addEventListener on the MediaQueryList API, this primitive will need to be polyfilled. If your application needs to support much older versions of the browser you should use a polyfill utility or patch the missing function like so:
if ((!"addEventListener") in MediaQueryList) {
MediaQueryList.prototype.addEventListener = function (type, callback) {
if (type === "change") this.addListener(callback);
};
MediaQueryList.prototype.removeEventListener = function (type, callback) {
if (type === "change") this.removeListener(callback);
};
}
See CHANGELOG.md
Thanks to Aditya Agarwal for contributing createBreakpoints.
FAQs
Primitives for media query and device features
The npm package @solid-primitives/media receives a total of 320,034 weekly downloads. As such, @solid-primitives/media popularity was classified as popular.
We found that @solid-primitives/media demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Socket uncovered 77 linked Firefox extensions, including 40 that steal wallet secrets or credentials and 37 deceptive sports-score shells.

Security News
NIST disclosed an unreleased AI tool called V-etalon and opened a broad inquiry into NVD modernization after years of automation plans produced no public enrichment system.

Security News
In his AI Council 2026 talk, Feross Aboukhadijeh covers recent package compromises, vulnerability discovery, and a more automated security model.