How to Add Dark Mode in SvelteKit with TailwindCSS

Need help with Svelte?

Book a complimentary 15-minute call, and I'll analyze your code base and provide you with individualized feedback.

Schedule a Call

This guide will show you how to add dark mode to your SvelteKit application using the following technologies:

Step 1: Set up Your SvelteKit Project

  1. Create a new SvelteKit project:
npm create svelte@latest dark-mode
cd dark-mode
npm install
  1. Install the mode-watcher and lucide-svelte packages:
npm install mode-watcher lucide-svelte
  1. Install tailwindcss and its peer dependencies, then generate your tailwind.config.js file:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
  1. Modify tailwind.config.js to add template file paths and the dark mode selector strategy:
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
	content: ['./src/**/*.{html,js,svelte,ts}'],
	darkMode: 'selector',
	theme: {
		extend: {}
	},
	plugins: []
};
  1. Create a app.css file in the src directory and add the TailwindCSS directives:
/* src/app.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
  1. Create a root +layout.svelte file in the src/routes directory and import the app.css file:
<!-- src/routes/+layout.svelte -->
<script lang="ts">
    import "../app.css";
</script>

<slot />

Step 2: Set the Application Background

In the src/app.html file, add bg-white dark:bg-slate-900 as classes to the HTML <body> tag. These classes set the background color to white in light mode and slate-900 in dark mode.

<!-- src/app.html -->
<!doctype html>
<html lang="en">

<head>
	<meta charset="utf-8" />
	<link rel="icon" href="%sveltekit.assets%/favicon.png" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	%sveltekit.head%
</head>

<body data-sveltekit-preload-data="hover" class="bg-white dark:bg-slate-900">
	<div style="display: contents">%sveltekit.body%</div>
</body>

</html>

You can find more information about how to style your site in dark mode in the TailwindCSS Docs.

Step 3: Create a Toggle Component

To enable users to switch between light and dark modes, you'll need to create a toggle button component. Create a ThemeToggle.svelte component in the src/lib directory:

<!-- src/lib/ThemeToggle.svelte -->
<script lang="ts">
	import Sun from 'lucide-svelte/icons/sun';
	import Moon from 'lucide-svelte/icons/moon';

	import { toggleMode, mode } from 'mode-watcher';
</script>

<button on:click={toggleMode} class="border rounded border-slate-200 dark:border-slate-600 p-1">
	{#if $mode === 'light'}
		<Sun class="size-4 text-slate-700" />
	{:else}
		<Moon class="size-4 text-slate-200" />
	{/if}
	<span class="sr-only">Toggle theme</span>
</button>

Component Details:

Step 4: Integrate ModeWatcher and ThemeToggle.svelte Components

Finally, add the ModeWatcher and ThemeToggle components to the root +layout.svelte file:

<!-- src/routes/+layout.svelte -->
<script lang="ts">
    import "../app.css";
    import { ModeWatcher } from 'mode-watcher';
    import ThemeToggle from '$lib/ThemeToggle.svelte';
</script>

<ModeWatcher />
<ThemeToggle />

<h1 class="text-slate-900 dark:text-white">
    Dark Mode
</h1>
<slot />

Optional: Set a Default Mode: By default, ModeWatcher detects the user's theme preference and applies the appropriate class. To set a specific default mode, add the defaultMode prop to ModeWatcher:

<ModeWatcher defaultMode={"dark"} /> <!-- "dark" or "light" -->

Step 5: Test Your Dark Mode Toggle

Now that everything is set up, it's time to test the dark mode toggle to make sure it works correctly.

  1. Start the development server:
npm run dev
  1. Open Your Application: Open your browser and navigate to http://localhost:5173.

  2. Toggle Dark Mode: Find the theme toggle button (Sun or Moon icon) and click the button to switch between light and dark modes.

  3. Verify Changes: Make sure the background color, header tag, and toggle icons update according to the mode.

Summary

You've successfully added dark mode to your SvelteKit application using TailwindCSS, Mode Watcher, and Lucide icons.

That's it! Happy coding.

Need help with Svelte?

Book a complimentary 15-minute call, and I'll analyze your code base and provide you with individualized feedback.

Schedule a Call