How to Use Claude Code to Add a Dark Mode Toggle
Claude Code can add a dark mode toggle to your app in a single session, generating the component, wiring up state, and applying CSS variables or Tailwind classes automatically. It works best when you give it your stack details upfront and let it drive the full change end-to-end. Keep an eye on your usage window before starting: dark mode refactors can consume a meaningful chunk of your 5-hour session limit.
- Claude Code handles the full toggle flow: component, state, persistence, and styling
- A typical dark mode implementation spans 3-8 files depending on your stack
- Claude Code usage resets every 5 hours, so starting a multi-file refactor near the end of a window risks an interruption mid-PR
What does Claude Code actually do when you ask it to add a dark mode toggle?
Claude Code doesn't just drop in a button. When prompted correctly, it will:
- Create a toggle component (button or switch) with accessible ARIA labels
- Set up state management using React context, Zustand, or a simple
useStatehook - Persist the user's preference to
localStorageso it survives page reloads - Apply the theme by toggling a class on
<html>or<body>, or by switching a CSS variable set - Respect the system preference via
prefers-color-schemeas a default
The output quality depends almost entirely on how specific your prompt is. Generic prompts produce generic boilerplate; targeted prompts produce production-ready code that fits your existing patterns.
How to prompt Claude Code for a dark mode toggle: step by step
Step 1: Orient Claude Code to your codebase
Before writing any prompt, run /init in your project root if you haven't already. This lets Claude Code read your file structure and understand your stack. For an existing project, you can also point it directly:
claude "Read src/App.tsx and src/styles/globals.css to understand how theming works in this project."
Step 2: Write a targeted implementation prompt
Specify your stack, your styling approach, and your persistence requirements in one shot. Here are proven prompts for the three most common setups:
React + CSS variables
Add a dark mode toggle to this React app. Use a ThemeContext to manage the current theme ('light' | 'dark'). Store the preference in localStorage. Apply the theme by setting a data-theme attribute on the html element. Define --bg-color and --text-color CSS variables for both themes in globals.css. Place the toggle button in the Header component.
Next.js + Tailwind CSS
Add dark mode to this Next.js app using Tailwind's 'class' strategy. Use next-themes to manage the theme. Create a ThemeToggle component using a sun/moon icon that calls useTheme() from next-themes. Add the ThemeProvider to _app.tsx. Make sure it avoids hydration mismatch.
Vanilla JS + CSS
Add a dark mode toggle to this vanilla JS project. No frameworks. Create a toggle button in index.html. On click, add or remove a 'dark' class on the body element. Store the preference in localStorage and read it on DOMContentLoaded. Add dark mode CSS variables in styles.css under body.dark.
Step 3: Review the diff before accepting
Claude Code will stage the changes and show you a diff. Before accepting, check:
- That the toggle component is placed where you actually want it (header, navbar, settings page)
- That
localStoragereads happen inside auseEffectto avoid SSR issues in Next.js - That your existing CSS custom properties aren't overridden unintentionally
Step 4: Handle edge cases with follow-up prompts
After the initial implementation, use targeted follow-ups:
- "Make the toggle respect the user's system preference on first visit using prefers-color-scheme."
- "Add a smooth transition on background-color and color changes when the theme switches."
- "Write a unit test for the ThemeContext that verifies localStorage persistence."
Using Claude Code slash commands during the process
Claude Code's built-in slash commands help you stay efficient throughout a dark mode implementation:
- /init: Index your project structure so Claude Code understands your file layout before writing code
- /review: Ask Claude Code to review the generated toggle component for accessibility issues or missing edge cases
- /usage: Check how much of your session limit you've consumed before starting a multi-file refactor
Running /usage before a significant change is a small habit that prevents the worst outcome: hitting your limit halfway through a refactor, with your codebase in a partially-modified state.
Why usage limits matter for multi-file changes like dark mode
A dark mode toggle sounds small, but it often touches more files than expected: a theme context file, a toggle component, a global stylesheet, a root layout component, and potentially a settings page. That is 4-6 file writes in a single session.
According to Anthropic's usage limit guidance, Claude Code sessions are subject to usage caps that reset on a rolling 5-hour window. If you start a complex implementation near the end of your window, Claude Code can cut out mid-task, leaving you with broken imports, half-written components, or a theme context that isn't wired up to anything.
Knowing your usage state before you start is the difference between shipping the feature and spending 20 minutes manually reverting an incomplete refactor. You can check with /usage inside Claude Code, or via the claude.ai settings page. For a persistent, always-visible indicator, Usagebar shows your current usage directly in the macOS menu bar without requiring you to context-switch out of your editor.
What Usagebar shows you
- Live usage percentage, updated in real time
- Smart notifications at 50%, 75%, and 90% of your limit so you know to wrap up or start fresh
- Exact reset time for your 5-hour window, so you can plan when to kick off long sessions
- Secure credential storage via macOS Keychain: no plain-text API keys
Get Usagebar: instant download, pay what you want (free for students).
Common issues when adding dark mode with Claude Code
| Issue | Cause | Fix to ask Claude Code for |
|---|---|---|
| Flash of unstyled content on load | Theme read happens after hydration | "Add a blocking script to read localStorage before React hydrates" |
| Toggle state resets on navigation | Context not at root level | "Move ThemeProvider to the root _app.tsx or layout.tsx" |
| Tailwind dark classes not applying | darkMode strategy set to 'media' not 'class' | "Set darkMode: 'class' in tailwind.config.js" |
| Toggle breaks SSR in Next.js | localStorage accessed on server | "Wrap localStorage access in typeof window !== 'undefined' check" |
Key takeaways
- Give Claude Code your full stack context upfront: framework, CSS strategy, and where the toggle should live
- Use the Next.js + next-themes prompt to avoid SSR hydration bugs automatically
- Run
/usagebefore starting: a dark mode refactor touches 4-6 files and can consume a noticeable share of your session - Use follow-up prompts for
prefers-color-schemesupport, transitions, and tests - Monitor your 5-hour reset window with Usagebar to avoid mid-task lockouts on critical PRs
Related reading
Track Your Claude Code Usage
Never hit your usage limits unexpectedly. Usagebar lives in your menu bar and shows your 5-hour and weekly limits at a glance.
Get Usagebar