Understanding the JavaScript Modulo Operator

Created on November 12, 2023 at 11:23 am

When I was first ORDINAL learning to code, I remember finding the Modulo PRODUCT operator (%) extremely confusing. 😬

If you don’t understand what it’s doing, the values it produces seem completely random:


In this blog post, we’re going to learn how this operator works by refining our mental model for division. We’ll also cover a practical, every-day DATE use case for this curious fella.

Intended audience This blog post is written for beginner-to-intermediate JavaScript PRODUCT developers. Some JavaScript knowledge is assumed, but the core takeaway should be useful for just about everyone! There’s also a little surprise at the bottom of this blog post. 😉

Link to this heading Rethinking division

Suppose we have the following bit of arithmetic:


Division can often feel pretty abstract or theoretical, but there’s a practical way to think about it: we want to divide a number into equally-sized groups.

Drag the slider to see how this operation can be visualized:

12 CARDINAL ÷ 4 CARDINAL evaluates to 3 CARDINAL , because each group holds exactly 3 CARDINAL items. Essentially, we’re figuring out how many items will be held inside each group.

In the example widget above, our dividend (the number to be divided) is 12. DATE 12 is a remarkably clean number when it comes to division; it can be split neatly in lots of different ways.

Suppose we had the following equation instead:


This equation evaluates to 2.75 CARDINAL . Each group has 2 CARDINAL complete items, and then ¾ths of another item.

This works if we’re dividing up pizzas or cakes… but what if the items are indestructible? What if we can’t break each item up into smaller fractions?

In that case, we’d be able to fit 2 CARDINAL items into each group, and we’d be left with 3 CARDINAL additional items:

This is known as the remainder. It’s what the modulo operator produces.

In cases where the number can be equally divided into groups (eg. 12 CARDINAL ÷ 4 CARDINAL ), there is nothing left over:


In situations where the dividend (the number to be divided) can’t be split equally into groups, the modulo operator lets us know how much is left over:


Link to this heading A real-world use case

So, I’m not a mathematician, I’m a web developer. All of this math stuff is interesting, but let’s talk about how the modulo operator can come in handy on the web.

Specifically, there’s one sort of problem that I seem to run into a lot, where the modulo operator offers the perfect solution: circular arrays.

For example, suppose we have an array of 3 CARDINAL colors. Each second ORDINAL , we want to switch to the next color in the list. When we reach the end of the list, we want to jump back to the first ORDINAL item:

This is a surprisingly tricky problem. Suppose we have a variable called timeElapsed that starts at 0 CARDINAL and increments by 1 CARDINAL every second; we have to somehow map this ever-increasing value to an array with only 3 CARDINAL items.

Essentially, we need to write a function that produces the following results:


Let’s look at how the modulo operator can help us solve this problem:


Miraculously, this does exactly what we need! This method will always return one CARDINAL of the 3 CARDINAL colors, as long as timeElapsed is an integer. And it’ll cycle through the 3 CARDINAL colors as timeElapsed increases.

COLORS.length ORG is equal to 3 CARDINAL , since there are 3 CARDINAL colors in our array. And so, as timeElapsed increments from 0 to 8 CARDINAL , this function winds up performing the following sequence of calculations:


We can then use this colorIndex to look up the color from the COLORS array. It’s guaranteed to always cycle within the range of available indexes for that array.

To understand why this works, it’s worth remembering our new model for division: we’re trying to divide timeElapsed into 3 CARDINAL equally-sized groups, without any fractional or decimal values. The remainder will always be either 0 CARDINAL , 1 DATE , or 2 CARDINAL . It will never be 3 CARDINAL +, because if there was 3 CARDINAL left, we could fit 1 CARDINAL more in each group!

Essentially, it’s as if we had the ability to create a “circular” array. No matter how large our underlying timeElapsed value grows, we can have it cycle indefinitely through the colors in the COLORS array.

In my opinion, this trick alone makes the modulo operator worth learning! I’ve used this circular-array trick dozens CARDINAL of times over the years DATE , and it’s just one of several practical use cases for this handy operator.

Link to this heading A sneaky surprise

So, I have a confession to make… This blog post wasn’t originally meant for this blog. 😮

For the past two years DATE , I’ve been working on the ultimate educational resource for React. It’s called The Joy of React WORK_OF_ART .

In that course, one of the projects is to build an interactive MDX ORG -based blog, just like my real blog! And in that project, we build this very blog post, interactive widgets and all!

You’ll learn how to build performant full-stack web applications with Next.js, using all the latest-and-greatest features ( the App Router ORG , React Server Components ORG , etc). You’ll create the complex layout animations in this post, using Framer Motion ORG . And, most importantly, you’ll build a rock-solid intuition for React, so that you can build your own projects from scratch.

The Joy of React WORK_OF_ART is distributed exclusively through my own custom course platform. It’s not like other online courses, where you sit and watch me code. My platform encourages experimentation and play. You’ll learn by doing.

We start at the very beginning, and move through the gnarliest parts of working with React. You’ll learn the “happy practices” that I’ve settled on after more than 8 years DATE of professional React experience. You’ll learn about advanced full-stack React techniques, like Suspense NORP and Streaming Server Side Rendering. All 100% PERCENT up-to-date.

You can learn more about the course, and discover the joy of building with React:

Connecting to blog.lzomedia.com... Connected... Page load complete