Create a Dark Mode of your app using Styled Components

Tom Nolan
The Startup
Published in
5 min readJun 4, 2019

Many applications and software packages have begun shipping an optional dark mode that a user can enable as an alternative to the default lighter mode. Aside from the aesthetic differences, there are many other benefits mentioned ranging from being less taxing on your device’s battery consumption to actual improvements on your health.

While we’re not actually going to get into the alternative benefits from using the dark mode in this article, we will go through implementing it using React and Styled Components!

What we’re going to build

The application is going to consist of a few basic, styled elements including a button that will allow the user to toggle between a light and a dark mode. In addition to toggling the mode, it will also save the user’s preference so that their selection is remembered when they return.

A few tools we’re going to use to help us build the app:

  1. Create React App (Bootstrapping the app)
  2. Styled Components (Themeing)
  3. Local Storage (Save the user’s selection)

You can check out a demo of the finished project here.

Part 1: Bootstrapping the App

As mentioned above, we’re going to utilize Create React App as a way to get our application up and running. If you do not already have Create React App installed, you can install it with:

npm install -g create-react-app

To initialize our new application run:

create-react-app dark-mode-toggle

Change into our new project directory:

cd dark-mode-toggle

And finally, let’s install the only additional dependency we will need — styled components:

npm install styled-components --save

Part 2: Build the App with a Light Theme

We’re going to initially build the application without the dark mode, so start by deleting all of the files from the current src directory of your project. Then let’s prepare the files:

  1. Inside of the src directory create two new folders — components and themes
  2. In the src/components directory, create an App.js, Button.js, Card.js, andContainer.js file
  3. In the src/themes directory, create a light.js file
  4. In the src directory, create an index.js and style.css file

When the above is complete, your folder structure should resemble:

.
└── src
├── index.js
├── style.css
├── themes
| └── light.js
└── components
├── App.js
├── Button.js
├── Card.js
└── Container.js

Now, let’s start writing some actual code! We’ll start in the src/themes/light.js file which will contain all of the colors required for the light mode.

In a real application, you will want to avoid naming conventions that pair 1:1 with a specific component and make them more universal, however, for the sake of this application, I’ve named the colors to their use-case.

Moving on to our src/index.js file to initialize our React application:

In the src/index.js file, we import the src/style.css file. To be clear, this stylesheet will not contain any of our theme’s styles, but one rule to just remove the default margin on the body element:

The next component we’re going to focus on will initially just provide the light theme we created above, but we will revisit it again later in this article when we add the logic to toggle the Dark theme. So, in src/components/App.js we’re going to:

  1. Import the light theme that we created above
  2. Provide our theme using Styled Component’s ThemeProvider
  3. Import and render the components that our app contains

In the src/components/App.js file we just created, we reference our three remaining components — Container, Card, and Button.

  • The Container is responsible for centering our content in the viewport
  • The Card is responsible for visually separating our content from the rest of the page
  • The Button component will be used to toggle the dark mode later on in the article

When we build each of these components below, we are going to make reference to the theme that is provided in the src/components/App.js file’s ThemeProvider. You can read more about how themes work with styled components here.

For our purposes, any time we reference a color, we will pull it off of our theme object using ${props => props.theme.colors.ourColorProperty}:

At this point, you should have an app that resembles:

Part 3: Providing a Dark Theme

Since we have a basic app that consumes a theme, let’s add a new theme! Create a new file in the src/themes directory called dark.js.

Inside that file, we’re going to copy paste the object from src/themes/light.js and just change the hex codes:

To test that our new theme works properly, let’s import it into our src/components/App.js file and swap that into our theme provider:

Once the above changes have been made, you should see the dark version of the application:

The last piece of this puzzle is to provide the ability to actually toggle between these two modes. We will do this by:

  1. Utilizing the useState hook for our useDarkMode state
  2. Conditionally passing a theme into the ThemeProvider based on the useDarkMode state
  3. Toggling the useDarkMode state when the button is clicked
  4. Saving the useDarkMode state into local storage to remember the user’s preference upon returning

Once that is all hooked up, clicked the button should toggle the theme mode and save it into local storage. You can test this out by enabling dark mode and refreshing, and you should still see the dark mode!

Final Thoughts

  • A button is not the greatest of UX patterns to toggle a theme, so in a production application, you may want to consider something more appropriate like a checkbox!
  • While this article focused on a dark mode, there’s no limit to the number of themes you could offer, so you could swap the boolean value for a selection of some sort that provides more options to the end user
  • As mentioned a bit earlier, the naming conventions used in the theme is far from ideal for a larger application, so more thought should typically be put into the names
  • The colors used in this application are from the Nord Color Theme

--

--