knobs

flip your site's dark mode, viewport, locale and location from inside the page. no code changes.

npm i -D devknobs

the panel on the right edge of this page is the real thing. press d.

how it works

rewrites your own @media rules through the cssom, so prefers-color-scheme, reduced motion, contrast and width breakpoints flip without touching your css.

patches matchmedia, innerwidth, navigator.language, geolocation and intl.datetimeformat, so your javascript sees the same world your css does.

one script tag, or one react element. nothing to configure, nothing shipped to production when you gate it.

knobs

scheme
system, light, dark. media rules + matchmedia + color-scheme for light-dark().
motion
system, reduce.
contrast
system, more.
locale
en, en-us, tr, de, fr, es, ar, he, ja, zh-cn. html lang, navigator.language, direction from the language or forced ltr/rtl.
geo
antalya, istanbul, berlin, london, new york, san francisco, tokyo, sydney, sao paulo, or custom lat/lng/timezone. geolocation + intl.datetimeformat + getTimezoneOffset.
text
13, 15, 17, 20 px root size.
width
full, 1024, 768, 390. rewrites min-width, max-width and range queries, patches innerwidth, fires resize.
outlines
draw a box around every element.
replay
restart every css animation on the page.

usage

script tag
<script src="https://unpkg.com/devknobs/dist/index.global.js"></script>
import
import { mount } from "devknobs";
mount();
react
import { DevKnobs } from "devknobs/react";

{process.env.NODE_ENV === "development" && <DevKnobs />}

in next.js app router, load it through next/dynamic so it drops out of production bundles.

limits

container queries, vw units, forced-colors, print, pointer type and network cannot be faked from inside a page. use devtools for those. cross-origin stylesheets keep their real media behaviour.