Introducing darkmodejs

Utility package for managing Dark Mode on the web, thanks to matchMedia and prefers-color-scheme media queries

By Luke Whitehouse on


External Link

darkmodejs is a small (<1KB!) package designed to utilise the matchMedia API in combination with the prefers-color-scheme media query to provide the ability to tailor your website's theme to the chosen theme of a user's Operating System.

Example application using darkmodejs in Windows 10 Firefox
Example application using darkmodejs in Windows 10 Firefox

It's lightweight and unopionated, so it'll feel right at home in any JavaScript application, irrespective of frameworks or methodologies. Key features include:

  • Tiny file size: With less than 1KB unminified, it's so tiny you'll probably forget it's there.
  • Fully customisable: Let darkmodejs set the listeners whilst you worry about what you want to do with them. It won't tell you what class names to append to the <body/>, that's all on you.
  • Open source: All code is under the MIT license, even the demo app, meaning you're free to use this on your personal or professional projects without worry.

🌐 Live demo on Netlify

💻 Code on Github

📦 Package with NPM


Requires an Operating System which supports Dark Mode:

  • macOS 10.14
  • iOS 13.0
  • iPadOS 13.0
  • Windows 10
  • ... or greater

Also requires support for the prefers-color-scheme media query. A complete list of supported browsers can be found on caniuse.


The package can be found on NPM at @assortment/darkmodejs

$ npm install @assortment/darkmodejs


Its dead easy to get started, with the full API being on Github

import darkmode from '@assortment/darkmodejs';

const config = { onChange: (activeTheme, themes) => {} };


If you need ES5 support, you can require the package instead.

const darkmode = require('@assortment/darkmodejs');

An example could be logging to console when a theme is active:

import darkmode from '@assortment/darkmodejs';

const onChange = (activeTheme, themes) => {
  switch (activeTheme) {
    case themes.DARK:
      console.log('darkmode enabled');
    case themes.LIGHT:
      console.log('lightmode enabled');
    case themes.NO_PREF:
      console.log('no preference enabled');
    case themes.NO_SUPP:
      console.log('no support sorry');

darkmode({ onChange });

Let me know what you think? I'm eager to continue updating this package with further improvements and features. This is only the first itteration and I'd love your help! Submit a Github issues and get involved.

Until next time 📦

Follow us on Twitter, Facebook or Github.
© Copyright 2021 Assortment.
Created and maintained by Luke Whitehouse.