npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nodebb-plugin-dark-skin

v1.0.1

Published

Admin-configurable dark skin for NodeBB with OS theme detection and a toggle

Readme

nodebb-plugin-dark-skin

Admin-configurable dark skin for NodeBB, with OS theme detection and a toggle.

Built for NodeBB 4.14+ and nodebb-theme-harmony.

What it does

  • Adds a dark skin whose colours you set in the ACP. The palette is compiled through NodeBB's own custom-skin pipeline, so every colour Bootstrap derives from your variables — button hovers, borders, table stripes — is computed correctly rather than patched afterwards.
  • Adds a toggle to the Harmony sidebar next to Harmony's own skin switcher, and to the mobile bar below the lg breakpoint. The switcher is left in place.
  • Follows the visitor's OS theme until they choose for themselves.
  • Works for guests: an explicit choice is stored in a cookie and applied during server-side rendering, so there is no flash of the wrong theme on reload.

Install

npm install nodebb-plugin-dark-skin

Then activate it in ACP → Extend → Plugins and rebuild:

./nodebb build && ./nodebb restart

Configure

ACP → Plugins → Dark Skin (the plugin's own entry in the admin sidebar). Seven fields:

| Field | Default | Drives | |---|---|---| | Skin name | Dark Skin | the name shown in the skin switcher | | Background | #1c1e22 | $body-bg, the dark end of the grey ramp | | Text colour | #e6e6e6 | $body-color, the light end of the grey ramp | | Primary / brand | #0d6efd | $primary | | Secondary surface | #2a2e33 | $body-secondary-bg, $light, $body-tertiary-bg | | Border | #3a3f44 | $border-color | | Link | blank | $link-color; blank uses the primary colour |

Colours are hex, three or six digits. An invalid value falls back to that field's default rather than to a light colour.

Saving rebuilds the skin on the next page load; no ./nodebb build is needed.

What gets derived

Six fields are not enough to darken Bootstrap 5.3 — its grey ramp, $light/$dark and the secondary/tertiary backgrounds all stay light unless they are set explicitly, which is why themes like Bootswatch's darkly declare several dozen variables. This plugin derives that set from the two anchors you already give it, and emits 23 variables in total:

  • $gray-100$gray-900 — interpolated from the text colour (light end) to the background colour (dark end), keeping Bootstrap's usual ramp direction.
  • $body-bg, $body-color, $body-emphasis-color — the last one is $black in stock Bootstrap and also drives table striping and hover overlays.
  • $body-secondary-bg, $body-tertiary-bg.
  • $light and $dark, inverted. Harmony's left sidebar is literally class="text-dark bg-light …", so without this it renders near-white against a dark body. The same inversion fixes .btn-light and .text-bg-light, which core and Harmony use in well over a hundred places.
  • $primary, $link-color, $link-hover-color — Bootstrap shades the hover colour towards black, which is the wrong direction over a dark background.
  • $border-color, $border-color-translucent.
  • $form-select-indicator-color and $form-switch-color — both are interpolated into inline SVG data URIs, and Bootstrap's defaults disappear against a dark control.

Everything else Bootstrap 5.3 derives from these, mostly through --bs-body-bg, --bs-secondary-bg and --bs-border-color.

How the light side works

This plugin owns the dark side only. The light side is whatever skin you have selected in ACP → Appearance → Skins, so your existing look is untouched.

Notes

  • The toggle appears in two places. On desktop it sits in Harmony's left sidebar, beside the skin switcher. Below the lg breakpoint that sidebar is hidden (d-none d-lg-flex), so the toggle is injected into the mobile bar instead, alongside search and notifications. Guests get it in both.
  • The OS preference is never persisted. It is applied client-side only, and it is never written to the visitor's account or to a cookie, so a member whose laptop is dark and whose phone is light gets the right skin on each. Once someone picks a skin — with this toggle or with Harmony's switcher — that choice wins from then on.
  • Honours the ACP "Disable custom user skins" setting: with it on, the plugin stays out of the way entirely.
  • The skin is registered in NodeBB's custom-skins list and tagged as belonging to this plugin. Skins you created by hand are never modified.
  • Deactivating the plugin does not remove its skin from NodeBB's custom-skins list — NodeBB has no reliable server-side deactivation hook. Remove it by hand in ACP → Appearance → Skins if you no longer want it listed.

Development

npm test

The modules under lib/ are pure: they never require NodeBB, so the unit tests run without a forum.

Licence

MIT — see LICENSE.