VOOZH about

URL: https://blog.logrocket.com/immer-and-immutable-js-how-do-they-compare/

⇱ Immer and Immutable.js: How do they compare? - LogRocket Blog


2021-01-12
1294
#vanilla javascript
Elizabeth Amaechi
32297
👁 Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

Immutability is not a new concept in programming. It serves as the basis for programming paradigms, such as pure functional programming. The whole idea is to avoid direct change to data after it has been created.

👁 The Immer and Immutable.js logos.

Below is a breakdown of what we’re going to discuss in this article:

  • Immutability in JavaScript
  • An introduction to Immer and Immutable.js libraries
  • A comparison between Immer and Immutable.js

🚀 Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

Immutability in JavaScript

JavaScript primitives like strings and numbers are known to be immutable. This is true because strings, for instance, can’t be changed by any method or operation. You can only create new strings.

Let’s consider the variable below:

var name = "mark cuban"
name = "John Steve"

You could argue that the data is mutable because the name variable was reassigned to another string, but this is not the case.

Reassignment is different from immutability. This is because even though the variable was reassigned, it didn’t change the fact that the string “Eze Sunday” exists. It’s the same reason why adding 3 to 13 wouldn’t change the original variable 13, or you turning 18 doesn’t change the fact that you were 17 before.

Even though variables may be reassigned, the immutable data still remains the same.

We’ve established from the example above that primitives are immutable, but that isn’t the end of the story. There are data structures in JavaScript that are mutable. One of them is arrays.

To demonstrate this, let’s declare a variable and set its value to be an empty array as shown below:

let arrOne = []

We can easily update the content of the above array by using the .push() function:

arrOne.push(2)

This will add the data, 2, to the end of the array, altering the original array that we previously had.

Intro to the Immer and Immutable.js libraries

JavaScript wasn’t written for its data to be exclusively immutable, but there are instances where you need an immutable array or map to easily keep track or keep a record of changes in a data set.

This is evident in the React framework, especially when dealing with states and props. This is where immutability libraries kick in. These libraries help optimize our application, making it easier to track changes in our application. In this article, will be looking at two major immutability libraries. Namely, Immer and Immutable.js.

Immer

Immer is one of the many immutability libraries out there that you can use in your application. According to its official website, Immer is based on the copy-on-write mechanism. The whole idea revolves around applying changes to a temporary draftState, which serves as a proxy to the current state. Immer will let you easily interact with your data while keeping all the benefits that come with immutability.

Installation

To use Immer instantly in your application use the following command:

<script src="https://cdn.jsdelivr.net/npm/immer"></script>

// It can also be installed in your application using NPM;
npm install immer
Or with yarn;
yarn add immer

Usage

With Immer, most immutability works are done with the help of a default function:

produce(currentState, producer: (draftState) => void): nextState

This function takes in the currentState and draftState and updates the nextState to reflect changes made to the draftState.


Over 200k developers use LogRocket to create better digital experiences

👁 Image
Learn more →

Example

Consider the code below:

import produce from "immer"
const baseState = [
 {
 todo: "Learn typescript",
 done: true
 },
 {
 todo: "Try immer",
 done: false
 }
]

New data can be added to the state using the Immer default function, as follows:

const nextState = produce(baseState, draftState => {
 draftState.push({todo: "Tweet about it"})
 draftState[1].done = true
})

The baseState in this case stays untouched, while the nextState would be updated to reflect changes made to draftState. You can learn more about Immer from its official website here.

Immutable.js

Immutable.js is another option to consider when looking for an immutability library. Immutable.js serves the same purpose as Immer, but it takes a different approach. It provides you with an API for data structures like maps and lists.

Installation

Immutable.js can be installed using npm:

npm install immutable

Example

We can perform mapping operations with Immutable.js by requiring map from the installed package and making use of it, like this:

const { Map } = require('immutable');

const map1 = Map({ a: 1, b: 2, c: 3 });

const map2 = map1.set('b', 50);

map1.get('b') + " vs. " + map2.get('b'); // 2 vs. 50

From the example above, our object { a: 1, b: 2, c: 3 } is wrapped with the Map() function. we went on to perform get and set operations on it while keeping the data Immutable.

In addition to objects, we can create immutable arrays using the List function as shown below:

List(['apple','orange','grape'])

The above is an array implementation in Immutable.js using the List function.

fromJS function helps bypass the need for wrapping our objects and arrays with Map({}) and List([]) functions by converting them directly into immutable data.

fromJS(['apple','orange','grape'])

The above converts the array directly into immutable data.

Immer v. Immutable.js: Which should you choose?

Now here is the big question: which should you choose between these two libraries? To start, let’s list out the benefits and downsides to these libraries individually. We’ll start with Immer.

Benefits that comes with Immer

There are lots of benefits that come with using Immer as opposed to making use of other libraries like Immutable.js. Some of these include:

  • Boilerplate reduction: With Immer, you write more precise code with no extra boilerplate, leading to an overall reduction in codebase
  • Immutability works with normal JavaScript data types and structures: Immer allows for the use of normal JavaScript, objects, maps and arrays without any need to learn a new API
  • Immer is strongly typed with no string-based paths selectors
  • Support for patches

Downsides to Immer as a library

There are a couple things that make using Immer difficult. For one thing, you need an environment that supports proxy objects to use Immer. Also, Immer does not provide support for complex object types like class instance.

Benefits that comes with Immutable.js

Just like Immer, Immutable.js has its benefits. Some of them includes:

  • In addition to other conventional javaScript data structures, Immer provides you with data structures that are not native to JavaScript. Some of them include ordered maps and record
  • Immutable,js lets you know the precise data that have been changed in your reducer, making development easier
  • Immutable.js writes data at record speed when compared to other immutable libraries

Downsides to Immutable.js

Though Immutable.js is fast at writing data, it is much slower when performing read operations.


More great articles from LogRocket:


Also, Immutable.js forces you to learn new and sometimes complex syntax and APIs just to perform basic operations. For instance, adding an extra data to an array will require the use of a .set() method, which isn’t traditional for JavaScript.

Immutable.js also forces you to use a unique construction type everywhere in your application. This means that for every immutable collection that you construct, you must make use of the appropriate Immutable.js collection rather than the traditional ones. This can cause a lot of stress, especially when migrating your code to another codebase that doesn’t use these collections.

Immer, on the other hand, offers roughly the same thing with much more flexibility. This is why many developers stick with it. It lets you create collections with classical objects that you’re already used to.

Conclusion

If you need faster writing speed in your application, you can go for Immutable.js. On the other hand, if you want to write less code while sticking with traditional JavaScript data structures and object types, then Immer is for you.

Overall, both Immer and Immutable.js are great libraries that you should try using in your application.

LogRocket: Debug JavaScript errors more easily by understanding the context

Debugging code is always a tedious task. But the more you understand your errors, the easier it is to fix them.

LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to see exactly what the user did that led to an error.

👁 LogRocket Dashboard Free Trial Banner

LogRocket records console logs, page load times, stack traces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

Try it for free.

👁 Image
👁 Image
👁 Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

Debug Next.js apps with AI agents and next-browser

Learn how next-browser gives AI agents runtime context for debugging Next.js apps, including React props, hydration, PPR, forms, and performance.

👁 Image
Emmanuel John
Jun 17, 2026 ⋅ 9 min read

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

👁 Image
Chizaram Ken
Jun 16, 2026 ⋅ 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.

👁 Image
Ikeh Akinyemi
Jun 12, 2026 ⋅ 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo — with email/password login, Google OAuth, session persistence, and protected routes.

👁 Image
Chinwike Maduabuchi
Jun 9, 2026 ⋅ 13 min read
View all posts

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now