The Ultimate Guide to JavaScript Web Storage: localStorage vs sessionStorage Explained

Introduction

In JavaScript, local storage and session storage are very handy tools, as they allow us to bring web development to the next level. We can save data locally in the browser to enhance user experience without any extra effort, such as toggling the theme color or managing cookies, and many other things — all without using any commercial online database.

Check out this short clip — now you will understand what I am saying:

Notice how it switches to dark mode when the button is clicked? This is not surprising, but the impressive thing is how it still stays in dark mode even after closing the entire browser and restart it. Hmm 🤔

It is quite impressive, isn’t it? The answer is simple — this is due to local storage. I implemented local storage in this project, so I didn’t need any external API for saving the dark mode theme that I clicked. This setting is saved locally in the browser’s local storage, so the browser won’t lose it as long as we don’t reset browser cookies or change back to the light mode.

This topic is simple yet widely used in development. I’m expecting that you would be somewhat familiar with this topic — that’s why you are here 😀. If you are completely unknown to this, you would still understand it by the end of this article. Choose an option from the given options below:

Are you familiar with this topic (local storage and session storage) already?

Your selection will be saved using sessionStorage, because I am using session storage to save your chosen option. It won’t be lost even if you refresh the page. It will only be lost when the tab is closed.

Today, we will dive deep into this topic. We'll understand everything by examining it under a microscope, using both visual and logical examples to make every concept crystal clear.

What are Local and Session Storage?

In JavaScript, browsers provide the Web Storage API, which has two types: localStorage and sessionStorage. There is not much difference between them, but even this small difference has a big impact.

  • Data stored in localStorage persists even after the browser is closed and can be accessed across all tabs of the same origin, meaning it is shared globally.
  • Data stored in sessionStorage lasts only as long as the specific tab is open. Once the tab is closed, the data is erased, and it is accessible only within that tab, not across other tabs like localStorage.

Check the example below and you will understand how it works. There are two buttons, localstorage and sessionstorage. When you click on them, they will store a value in the browser storage, in their corresponding place. Click on both buttons and see what happens!

LocalStorage vs SessionStorage Demo

Click the buttons below. Then open your browser’s DevTools → Application tab and check the Local Storage and Session Storage sections. You’ll see twicedev.com saved in both.

Now, right-click anywhere on the page and open the inspect tool, then choose the application tab and check the localstorage and sessionstorage sections. You will see twicedev.com saved both in local and session storage. You can see that I’m localStorage is saved in the localstorage section, while I’m sessionStorage is stored in the sessionstorage section.

When you clicked the buttons, I set the corresponding values for each button — like (I’m localStorage) for the localStorage button, and (I’m sessionStorage) for the sessionStorage button.

Have you seen how we successfully stored the value in web storage? Don’t worry, I will show you how I stored it with code later; right now, I’m just showing you how it works.

If you remember, I mentioned that the localStorage value can be accessed across all tabs, while the sessionStorage value cannot be accessed in other tabs except the one where it is stored. Let’s prove this, as I never go ahead without backing up my points 😀. Let’s quickly test this.

Open a new tab by clicking on the plus (+) button in your browser beside the current tab, and then copy this article link and paste on that tab and then open inspect tool in that tab. Check the localstorage and sessionstorage. You will see that I’m localStorage is still visible in the new tab for the twicedev.com website, while I’m sessionStorage is not shown.

Did you notice the difference? But if you go back to the original twicedev.com tab where you are reading this blog post, you will see that I’m sessionStorage is still saved in the sessionStorage section. You can refresh this page, and it won’t be erased, as long as you don’t close this tab.

Take a look at this to-do list, which utilizes localStorage to save data. Open it and add a few dummy tasks, then close the tab. When you open it again, you will see the tasks you created are still there in the to-do list. They won’t be erased unless you manually remove them from storage, even if you close the browser.

Now take a look at another to-do list, which utilizes sessionStorage to save data. Open it in a new tab and add a few tasks, just like you did in the recent to-do list. Now, close the tab—you’ll see that the tasks you added have been erased.

I hope you now clearly understand the difference between the two.

Let’s now ask: Why is it useful?

Why use web storage?

Maybe you're wondering, Why is this useful? If so, you're asking the right question. Let me show you a few scenarios that will help you understand its value.

Let’s say you have a website and you want to implement a dark and light mode functionality so users can choose the mode they’re most comfortable with. Some people prefer dark mode, while others might prefer light mode due to vision issues. So, how would you implement this functionality effectively without using local storage?

Sure, you can implement the dark/light mode toggle, and it will work. But if you don’t use localStorage, do you know how your website or app will behave? Obviously, not well at all. Take a look at the example below:

Have you seen the video above, where I turned the website into dark mode and then navigated to a different page? Everything changed when I navigated to the new page—it switched back to the default (light) mode. Do you know why? Because I didn’t use web storage (localStorage or sessionStorage).

You might ask: Why didn't it stay in dark mode even though I had it enabled in the same tab? Why do I still have to turn on dark mode for each new tab?

When a new page is loaded, the JavaScript on that page runs from scratch. Any functionality controlled by JavaScript — like switching to dark mode—only stays active as long as the page remains open. Once the page is reloaded or you navigate to a different page, the JavaScript state is lost, and the functionality resets unless you store the state using something like localStorage.

This is why, in the video example above, when I navigated to a new page, the dark mode setting was lost and reset to the default light mode.

Now you can understand that without using the Web Storage API, we can’t implement this kind of functionality effectively with JavaScript alone. However, there are two ways to achieve it:

Using an external API, where we send the user's preference (e.g., switching to dark mode) to a backend server. This approach is often too complex and expensive for such a simple task. Managing external APIs requires time, infrastructure, and sometimes money. It also adds unnecessary network requests, which could hurt the user experience.

Using the Web Storage API, which is a much more efficient and powerful solution for these kinds of use cases. It doesn’t require any internet connection, it’s free to use, and it provides a faster user experience. By saving the functionality state in localStorage, we can retain user preferences like dark mode across page reloads or navigation — without any extra effort.

I hope you’ve understood the value of Local Storage and Session Storage. Now, let’s learn how to implement them practically.

How does web storage work?

As we’ve already covered their purpose and functionality, it’s time to see how to use them in practice—so you can apply them in your next cool project 😎.

Before we dive in, let me clarify one important thing: There’s no difference in how you write code for Local Storage and Session Storage. The only difference lies in their behavior. In other words, the syntax is almost identical for both. You can check the table below:

localStoragesessionStorage
Lifetime: Stays until manually clearedLifetime: Cleared when tab/window closes
Scope: Accessible in all tabs of same siteScope: Accessible only in current tab/window
Capacity: ~5–10MBCapacity: ~5MB
Use Cases: Store user preferences, tokens, etc.Use Cases: Temporary state (e.g., wizard forms)

Have you seen the table? It shows the differences between Local Storage and Session Storage.

I believe you’ll be able to understand the table and the distinctions it presents, as I’ve made it as simple as possible.

The first two differences — the main ones — were already explained above with interactive examples. The remaining two are fundamental and are easy to grasp.

Now, check out another table that lists all the methods available in Web Storage (both Local Storage and Session Storage):

Method / PropertyDescription
setItem(key, value)Stores a key-value pair as a string
getItem(key)Retrieves the value associated with the key
removeItem(key)Removes the key-value pairs
clear()Removes all key-value pairs from storage
key(index)Returns the key at a given index
length (property)Returns the number of stored items

Have you noticed that there are six methods supported by both localStorage and sessionStorage? These methods are identical for both, with the only difference being how they behave — as I mentioned earlier. Let’s explore each of them in detail.

setItem

The setItem method is used to save data to web storage. It accepts two arguments: a key and a value. In both localStorage and sessionStorage, the data is stored in a format that resembles an object, even though web storage only allows strings to be stored — no numbers, objects, or other data types.

Although the data appears to be structured like an object, it is stored as string key-value pairs. That’s why each item has a unique key and associated value, similar to how an object in JavaScript looks:

JavaScript

copy

obj = {
name: 'John',
}

In the example above, name is the key, and John is the value. Similarly, when using setItem, the syntax follows the same principle: setItem(key, value).

JavaScript

copy

localStorage.setItem("user", "John");

This is the line of code I wrote to store a small piece of data in localStorage. As you can see, since I'm storing data in localStorage, I used localStorage.setItem("user", "John").

If I wanted to store the same data in sessionStorage, I would use sessionStorage.setItem("user", "John") instead.

Have you noticed? The method is the same — the only thing that changes is where we choose to store the data. We just specify either localStorage or sessionStorage before calling the method.

Check out the example below to see how the data is stored when you run this line of code in your browser:

setItem Preview Example

In the example above, I stored only one value — John. However, we can store many values for a specific key. For instance, if we want to store the full information of a person, we can use an object, because an object can hold multiple values of different types.

Check out the example below to understand better:

JavaScript

copy

localStorage.setItem("person", JSON.stringify({ name: "John", age: 22, gender: "male" }));

Notice that I used the JSON.stringify() method to store the object in localStorage. Why? Because the Web Storage API only supports strings. You can't store objects or other data types directly.

The JSON.stringify() method in JavaScript converts an object into a string. This allows us to store complex data structures like objects in localStorage.

It's important to understand that JSON.stringify() is not tied exclusively to the Web Storage API — it's a general-purpose method used whenever we need to convert an object into a string, including for APIs, logging, or saving data.

So, in summary: we use JSON.stringify() when storing objects in localStorage because localStorage only supports string values.

getItem

The getItem() method works similarly to setItem(). Just as setItem() is used to save data in localStorage, getItem() is used to retrieve data from localStorage — for displaying on the screen or for further processing. It accepts one argument: the key. This key is used to access the specific value stored in localStorage.

JavaScript

copy

localStorage.setItem("person", JSON.stringify({ name: "John", age: 22, gender: "male" }));
const getPerson = localStorage.getItem("person");

console.log(getPerson); 
// Output: {"name":"John","age":22,"gender":"male"}

As shown in the example above, I used localStorage.getItem("person") to access the data stored under the key "person". Although the value looks like an object, it's actually a string, because the Web Storage API only stores data as strings. That's why we used JSON.stringify() when saving the object.

To convert this string back into an actual JavaScript object, we use the JSON.parse() method:

JavaScript

copy

const getPerson = localStorage.getItem("person");

console.log(JSON.parse(getPerson)); 
// Output: { name: "John", age: 22, gender: "male" }

As you can see, I used JSON.parse() to convert the string back into an object. This method is built into JavaScript and is not exclusive to localStorage. It can be used anytime you need to convert a JSON-formatted string into an object.

Check out this short image to visually reinforce the concept.

getItem Preview Example

As shown in the image, when a task is added to localStorage, it also appears on the screen. Do you know how that happens? It’s because the to-do list uses the getItem() method to retrieve the stored task and render it in the browser.

This helps you better understand how localStorage works in practice.

removeItem

The removeItem method works similarly to the getItem method. It is used to remove a specific item from web storage. Like getItem, it accepts one argument — the key — but instead of retrieving the item, it removes it from storage.

JavaScript

copy

localStorage.setItem("person1", JSON.stringify({ name: "John", age: 22, gender: "male" }));
localStorage.setItem("person2", JSON.stringify({ name: "John", age: 22, gender: "male" }));
removeItem Preview Example 1

Have you seen? I have saved two objects in localStorage — person1 and person2. Now, we will remove person1 from localStorage using removeItem.

JavaScript

copy

localStorage.removeItem("person1");
removeItem Preview Example 2

As shown in the image above I used localStorage.removeItem("person1") to remove the person1 item from storage. Now, you can see that only one item remains in localStorage — person2. Since person1 was the key, I passed it into the removeItem method to remove the corresponding item.

clear

The clear() method removes all key–value pairs from localStorage for the specific origin (i.e., the same domain, protocol, and port). It works like a function is called.

JavaScript

copy

localStorage.setItem("person1", JSON.stringify({ name: "John", age: 22, gender: "male" }));
localStorage.setItem("person2", JSON.stringify({ name: "John", age: 22, gender: "male" }));
localStorage.setItem("person3", JSON.stringify({ name: "John", age: 22, gender: "male" }));
clearItem Preview Example 1

Check the example above — I have saved three items in localStorage. Now, I will use the clear() method, which will remove all of these items from localStorage for this page (i.e., for this site).

JavaScript

copy

localStorage.clear()
clearItem Preview Example 2

Have you seen above? Since I used the clear() method, it removed all the data stored in localStorage for this domain. Remember, data from other domains won’t be erased — only data for this specific origin is affected.

key

The key(index) method is similar to the getItem(key) method, but there’s one key difference: getItem(key) is used to retrieve a value based on the provided key, while key(index) is used to retrieve the key name based on its position in localStorage.

For example, if we have two items saved in localStorage, and we want to get the key of the second item, we would use key(1) — because in JavaScript, indices start from 0, so the second item is at index 1.

JavaScript

copy

localStorage.clear();
localStorage.setItem("person1", JSON.stringify({ name: "John", age: 22, gender: "male" }));
localStorage.setItem("person2", JSON.stringify({ name: "John", age: 22, gender: "male" }));

You can see that I first cleared the localStorage using the clear() method, then saved two items: person1 and person2. This setup allows me to use the key() method in the next operation.

JavaScript

copy

const getKey = localStorage.key(1);
console.log(getKey);
// Output: "person2"

Have you noticed? I used localStorage.key(1) to get the second item’s key, which is at index 1. It returns the key of the second item, which is person2.

length

The length property (not method) is used to check how many items are saved in web storage. For example, if I have 2 items saved in my localStorage, and I want to check how many items are stored for this specific domain, it will return the number 2.

JavaScript

copy

// Clear localStorage to start fresh
localStorage.clear();

// Add two items to localStorage
localStorage.setItem('person1', 'John');
localStorage.setItem('person2', 'Alice');

// Check how many items are stored
const numberOfItems = localStorage.length;

console.log(numberOfItems); // Output: 2

Have you seen the example above? I cleared the localStorage, then saved two items, and finally used the localStorage.length property to find out how many items are saved in localStorage for the given domain. It returned 2, which is the expected output.

This topic is very useful in web development, and thankfully, it is not as difficult as its importance suggests. If we want to work with sessionStorage, the methods and techniques are basically the same. The only difference is that instead of using localStorage.setItem, we use sessionStorage.setItem — simply replacing the word before the dot (.) and keeping the method name the same.