dark-mode-switch: a Bootstrap theme toggle that costs 383 bytes
Add a dark-mode theme toggle with a Bootstrap Custom Switch
At a glance
- What is it?
- dark-mode-switch is a small JavaScript file that turns a Bootstrap custom switch into a dark mode toggle, setting data-theme="dark" on the body element and remembering the choice in localStorage. It ships as a single script, a stylesheet you are expected to edit, and one tag in your page.
- Who is it for?
- dark-mode-switch fits a Bootstrap site that wants a dark mode toggle this month rather than a theming system, and where the site owner is willing to write the dark palette in CSS. It is the wrong tool if you need automatic theme detection, a class-based theming approach, or support outside Bootstrap, because the whole mechanism is a single attribute on the body element plus a localStorage flag.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly HTML, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The whole library is one attribute on the body tag
The mechanism is simpler than most toggles. Turning dark mode on adds `data-theme="dark"` to the `body` tag, and you can use CSS to target the elements on the page like so:
[data-theme="dark"] {
background-color: #111 !important;
color: #eee;
}That is the entire contract between the JavaScript and your stylesheet. There is no CSS custom property switching, no class on the root element, no theme object. Your styling rules hang off an attribute selector, and the script's only job is to set that attribute and to remember what the user chose. The README also notes that the preference is saved with localStorage, so the choice survives a reload, and that 0 and 1 are not the only values involved since the switch can be toggled in either direction. The audience is a front-end developer on a Bootstrap site who wants a working toggle in an afternoon.
Bootstrap 4 and Bootstrap 5 need different markup
Because the toggle is a Bootstrap custom switch, the markup differs between the two major versions, and the README gives both. For Bootstrap 4.x the wrapper uses the custom control classes:
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="darkSwitch" />
<label class="custom-control-label" for="darkSwitch">Dark Mode</label>
</div>
<script src="dark-mode-switch.min.js"></script>For Bootstrap 5.x the classes were renamed to form check and form switch:
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" id="darkSwitch" />
<label class="custom-control-label" for="darkSwitch">Dark Mode</label>
</div>
<script src="dark-mode-switch.min.js"></script>Note the small inconsistency in the Bootstrap 5 example, where the label keeps the older `custom-control-label` class while the wrapper and input use the new ones. The script tag is identical in both cases, which tells you the JavaScript is not sensitive to the Bootstrap version and keys off the input id `darkSwitch` instead. That is also the practical consequence for you: if you use a different id, the script will not find the switch.
The stylesheet is yours to write, and the shipped one is a placeholder
The usage steps say to edit the `dark-mode.css` to suit your site, and point out that the one included here is a basic example. That sentence is the honest description of the whole arrangement. The library gives you the mechanism, the attribute, and the persistence. The actual dark palette, which is the part users see, is yours to write, and the size of that job depends entirely on how much of your design system is expressed in Bootstrap utility classes versus custom CSS. The demo page at coliff.github.io/dark-mode-switch shows the Bootstrap 5 version, and the repository root holds `index.html` alongside `dark-mode-switch.js`, `dark-mode-switch.min.js` and `dark-mode.css`, so the whole implementation fits in a few files you can read end to end. The source is credited to two codyhouse.co tutorials on a dark and light switch with CSS and JavaScript and on storing theme colour preferences with localStorage.
Four ways to get it, and the npm package is the smallest one
The README lists several quick start options. You can download the latest release as a zip from the v1.0.0 tag, clone the repository with `git clone https://github.com/coliff/dark-mode-switch.git`, install it with npm using `npm install dark-mode-switch`, or add it with yarn using `yarn add dark-mode-switch`. Whichever route, the artefact is the same: the package `main` field points at `dark-mode-switch.min.js`, and the published `files` list contains the source, the minified file, the stylesheet, the LICENSE, the package.json and the README. The npm package name is `dark-mode-switch`, and the project page is at coliff.github.io/dark-mode-switch. Since the file is a plain script tag rather than a module, the npm route is mostly for teams who want the file in their build output and their dependency lockfile, which is what the package manifest is set up for.
The build is Prettier, ESLint, and Terser with ecma 5 output
The package scripts show the toolchain, and it is worth knowing because it constrains what syntax the output can contain. The `build` script runs prettier, then the test, then the minify step, and the minify step is `terser --ecma 5 --keep-classnames --keep-fnames --output dark-mode-switch.min.js -- dark-mode-switch.js`. Targeting ecma 5 is a deliberate choice for a file that goes straight into a script tag, and keeping class names and function names preserves the ids the script looks for. The test is `eslint dark-mode-switch.js`, formatting is `prettier --write dark-mode-switch.js`, and there are additional scripts for `htmlhint` against `index.html` and `cspell` over the markdown and JavaScript. The repository uses the GitHub Super-Linter workflow, and the `volta` field pins Node 22.22.2, so the toolchain is reproducible if you fork it.
Android WebView needs DOM Storage enabled, which is the one real trap
There is a section on enabling dark mode in an Android WebView, and it is the most likely thing to waste an afternoon on. You need the DOM Storage API in order for this to work with WebView, and inside OnCreate under the WebView you paste `WebSettings.setDomStorageEnabled(true)`. That is the whole instruction, and it exists because the toggle persists the preference in localStorage, and a WebView without DOM Storage has no localStorage, so the switch silently forgets what the user chose on every launch. The browser support note is otherwise generous, saying it works well with all the browsers supported by Bootstrap 4 and Bootstrap 5, and the project links both supported browser pages. The licence is MIT, the version in the package manifest is 1.0.1, the last tagged release listed is v1.0.0 from 2019-07-03, and the last push was on 2026-10-01.
Editorial conclusion
dark-mode-switch fits a Bootstrap site that wants a dark mode toggle this month rather than a theming system, and where the site owner is willing to write the dark palette in CSS. It is the wrong tool if you need automatic theme detection, a class-based theming approach, or support outside Bootstrap, because the whole mechanism is a single attribute on the body element plus a localStorage flag. Before you adopt it, look at the shipped `dark-mode.css` and plan to replace it with your own palette, and check how it interacts with any component that sets its own background, since the README's own example reaches for `!important` to win that fight.
Frequently asked questions
How do I install dark-mode-switch?
The README lists four options: download the latest release zip from the v1.0.0 tag, clone the repository with `git clone https://github.com/coliff/dark-mode-switch.git`, install with `npm install dark-mode-switch`, or add it with `yarn add dark-mode-switch`. The package's main entry is `dark-mode-switch.min.js`.
How does dark-mode-switch toggle the theme?
Turning dark mode on adds `data-theme="dark"` to the `body` tag, and you style the page with an attribute selector such as `[data-theme="dark"]`. The preference is saved with localStorage so the choice survives a reload.
What is the difference between the Bootstrap 4 and Bootstrap 5 markup?
Bootstrap 4.x uses `custom-control custom-switch` with a `custom-control-input` checkbox, while Bootstrap 5.x uses `form-check form-switch` with a `form-check-input` checkbox. In both examples the input has the id `darkSwitch` and the script tag loads `dark-mode-switch.min.js`.
Why does dark mode not stick in an Android WebView?
The WebView needs the DOM Storage API for localStorage to work, so inside OnCreate under the WebView you have to paste `WebSettings.setDomStorageEnabled(true)`. Without it the preference is not stored and the toggle resets on every launch.
Do I have to write the dark theme CSS myself?
Yes. The README says to edit the `dark-mode.css` to suit your site, and notes that the one included in the repository is a basic example. The library supplies the attribute, the script, and the persistence, and the palette is yours.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/coliff-dark-mode-switch)Was this useful?