On load

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode
}

In real time

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
    const newColorScheme = event.matches ? "dark" : "light";
});

I use this method in my frontend links page. На момент написания это выглядит так:

In CSS, I just added a dark theme class that got dynamically mixed to the page class, rewriting colors with specificity (two classes). Not by BEM, but as often advised, I did it first to make it work) Then maybe I’ll rewrite it under BEM.

.dark.page {background-color:#002B36;} 
.dark header {color:#c3d5d9;} 
and so on

JS:

const page = document.querySelector('.page');
// Theme switch buttons
const lightThemeLink = document.querySelector('.themes__link_light');
const darkThemeLink = document.querySelector('.themes__link_dark');

// Check if user set dark theme before
if (localStorage.getItem('themeIs') == 'Dark') {
	page.classList.add('dark');
}

// Check if user prefers dark theme
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
	page.classList.add('dark');
}

// Check theme preference switch real time
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
	const newColorScheme = event.matches ? 'dark' : 'light';
	if (newColorScheme == 'dark') {
		page.classList.add('dark');
	}
	if (newColorScheme == 'light') {
		page.classList.remove('dark');
	} 
});

// Turn dark theme on
darkThemeLink.addEventListener('click', setDark);
function setDark(el) {
	el.preventDefault();
	page.classList.add('dark');
	localStorage.setItem('themeIs', 'Dark');
}

// Turn light theme on
lightThemeLink.addEventListener('click', setLight);
function setLight(el) {
	el.preventDefault();
	page.classList.remove('dark');
		localStorage.setItem('themeIs', 'Light');
}

This about to cover all cases

CSS has a prefers-color-scheme media query, but it has much less support and you can’t do it without JS anyway (interactive switching).

To fix white flashing during page loading use this method.