Question

How to Store JavaScript Objects in localStorage and sessionStorage

javascripthtmllocal-storage

Question

I want to store a JavaScript object in HTML5 localStorage, but it seems to be converted into a string.

I can store and retrieve primitive values and arrays, but plain objects do not appear to work the way I expect. Should objects be stored directly?

Here is the code:

var testObject = { one: 1, two: 2, three: 3 };
console.log('typeof testObject: ' + typeof testObject);
console.log('testObject properties:');
for (var prop in testObject) {
  console.log('  ' + prop + ': ' + testObject[prop]);
}

// Put the object into storage
localStorage.setItem('testObject', testObject);

// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');

console.log('typeof retrievedObject: ' + typeof retrievedObject);
console.log('Value of retrievedObject: ' + retrievedObject);

This produces output like:

typeof testObject: object
testObject properties:
  one: 1
  two: 2
  three: 3
typeof retrievedObject: string
Value of retrievedObject: [object Object]

It looks like setItem() converts the value to a string before storing it. I see the same behavior in Safari, Chrome, and Firefox, so this seems more like a misunderstanding of Web Storage than a browser bug.

Why does this happen, and what is the easiest way to store and retrieve JavaScript objects in localStorage or sessionStorage?

Short Answer

By the end of this page, you will understand why localStorage and sessionStorage store values as strings, how to save JavaScript objects using JSON.stringify(), and how to restore them with JSON.parse(). You will also learn common pitfalls, practical usage patterns, and how this is handled in real applications.

Concept

localStorage and sessionStorage are part of the Web Storage API. They are simple key-value stores in the browser, and both store values as strings.

That means when you do this:

localStorage.setItem('testObject', testObject);

JavaScript tries to convert testObject into a string. A plain object becomes:

"[object Object]"

So the problem is not that the object is partially stored. It is that the object is being converted to its default string representation before storage.

To store objects correctly, you must:

  1. Convert the object into a JSON string with JSON.stringify()
  2. Save that string to storage
  3. Convert it back into an object with JSON.parse() when reading it

Example:

var testObject = { one: 1, two: 2, three: 3 };
localStorage.setItem('testObject', JSON.stringify(testObject));

var retrievedObject = JSON.parse(localStorage.getItem('testObject'));
console.log(retrievedObject.two); // 2

This matters because browsers often use Web Storage for:

  • user settings
  • shopping cart data
  • cached API responses
  • form drafts
  • feature flags
  • session state

If you do not serialize your data properly, you lose structure and cannot reliably reconstruct the original object.

Mental Model

Think of localStorage like a notebook where every note must be written as text.

  • Numbers can be written as text
  • Booleans can be written as text
  • Arrays can be written as text
  • Objects must also be written as text

But if you hand the notebook a raw JavaScript object, it does not know how to preserve the full structure. It just writes the object's default label:

[object Object]

JSON.stringify() is like translating your object into a text format the notebook can store accurately.

JSON.parse() is like reading that text and rebuilding the original object.

So the workflow is:

  • before saving → translate object to JSON text
  • after loading → rebuild object from JSON text
Take Quiz

Syntax and Examples

The standard pattern is:

localStorage.setItem('key', JSON.stringify(value));
var value = JSON.parse(localStorage.getItem('key'));

Storing a plain object

var user = {
  name: 'Ava',
  age: 29,
  isAdmin: false
};

localStorage.setItem('user', JSON.stringify(user));

Retrieving the object

var storedUser = localStorage.getItem('user');
var userObject = JSON.parse(storedUser);

console.log(userObject.name); // Ava
console.log(userObject.age);  // 29

Using sessionStorage

sessionStorage works the same way, but the data lasts only for the current browser tab session.

var settings = {
  theme: 'dark',
  sidebarOpen: true
};

sessionStorage.setItem('settings', JSON.stringify(settings));
var savedSettings = JSON.parse(sessionStorage.getItem('settings'));

Safe retrieval when the key may not exist

If the key is missing, getItem() returns null. Parsing null directly is often okay, but many developers prefer an explicit fallback.

var raw = localStorage.getItem('user');
var user = raw ? JSON.parse(raw) : null;

Example with an array of objects

var products = [
  { id: 1, name: 'Keyboard' },
  { id: 2, name: 'Mouse' }
];

localStorage.setItem('products', JSON.stringify(products));

var loadedProducts = JSON.parse(localStorage.getItem('products'));
console.log(loadedProducts[0].name); // Keyboard

Important limitation

JSON works well for plain data, but not for everything. For example:

  • functions are not stored
  • undefined is not preserved in the usual way
  • Date objects become strings
  • class instances lose their methods

Step by Step Execution

Consider this example:

var testObject = { one: 1, two: 2 };
localStorage.setItem('testObject', JSON.stringify(testObject));
var rawValue = localStorage.getItem('testObject');
var retrievedObject = JSON.parse(rawValue);

console.log(rawValue);
console.log(retrievedObject);
console.log(retrievedObject.two);

Step-by-step

  1. testObject is created as a JavaScript object.

    { one: 1, two: 2 }
    
  2. JSON.stringify(testObject) converts it into a JSON string.

    '{"one":1,"two":2}'
    
  3. localStorage.setItem('testObject', ...) stores that JSON string under the key testObject.

  4. localStorage.getItem('testObject') reads the value back.

    At this moment, the result is still a string:

    '{"one":1,"two":2}'
    
  5. JSON.parse(rawValue) converts the JSON string back into a JavaScript object.

    { one: 1, two: 2 }
    
  6. retrievedObject.two accesses the property normally and returns 2.

What happens in the broken version?

If you skip JSON.stringify():

localStorage.setItem('testObject', testObject);

JavaScript converts the object to a string automatically:

"[object Object]"

That string is what gets stored, so the object structure is lost.

Real World Use Cases

Web Storage is commonly used for small amounts of browser-side data.

Common examples

  • User preferences

    • theme (dark or light)
    • language choice
    • layout settings
  • Shopping cart state

    • product IDs
    • quantities
    • selected options
  • Draft form data

    • unsaved text input
    • multi-step form progress
  • Cached API data

    • recently fetched responses
    • profile information
    • dashboard filters
  • Session-only UI state

    • active tab
    • modal dismissal state
    • temporary navigation context

Example: saving a shopping cart

var cart = [
  { id: 101, name: 'Book', quantity: 2 },
  { id: 305, name: 'Pen', quantity: 1 }
];

localStorage.setItem('cart', JSON.stringify(cart));

var savedCart = JSON.parse(localStorage.getItem('cart')) || [];
console.log(savedCart.length); // 2

Example: saving a form draft

var draft = {
  title: 'My article',
  body: 'Work in progress...'
};

localStorage.setItem('draft', JSON.stringify(draft));

These use cases all depend on converting structured data into strings before storage.

Take Quiz

Real Codebase Usage

In real projects, developers usually wrap Web Storage access in helper functions instead of calling JSON.stringify() and JSON.parse() everywhere.

Common helper pattern

function saveToStorage(key, value) {
  localStorage.setItem(key, JSON.stringify(value));
}

function loadFromStorage(key) {
  var raw = localStorage.getItem(key);
  return raw ? JSON.parse(raw) : null;
}

Why helpers are useful

  • reduce repeated code
  • keep serialization logic in one place
  • make error handling easier
  • allow fallback values
  • simplify testing

Guard clause pattern

function loadSettings() {
  var raw = localStorage.getItem('settings');
  if (!raw) return { theme: 'light' };

  return JSON.parse(raw);
}

This is a guard clause: return early if the data does not exist.

Validation pattern

Stored data may be old, corrupted, or manually edited in developer tools.

function loadUser() {
  var raw = localStorage.getItem('user');
  if (!raw) return null;

  var user = JSON.parse(raw);
  if (!user.name) return null;

  return user;
}

Error handling pattern

If invalid JSON is stored, JSON.parse() throws an error.

function safeLoad(key, fallback) {
  try {
    var raw = localStorage.getItem(key);
    return raw ? JSON.parse(raw) : fallback;
  } catch (error) {
    return fallback;
  }
}

Update pattern

A common workflow is:

  1. load existing data
  2. modify it
  3. save it back
var todos = JSON.parse(localStorage.getItem('todos')) || [];
todos.push({ text: 'Learn localStorage', done: false });
localStorage.setItem('todos', JSON.stringify(todos));

This read-modify-write cycle is extremely common in browser applications.

Common Mistakes

1. Saving objects without JSON.stringify()

Broken code:

var user = { name: 'Sam' };
localStorage.setItem('user', user);

Result:

"[object Object]"

Fix:

localStorage.setItem('user', JSON.stringify(user));

2. Forgetting to parse after reading

Broken code:

localStorage.setItem('user', JSON.stringify({ name: 'Sam' }));
var user = localStorage.getItem('user');
console.log(user.name); // undefined

user is a string, not an object.

Fix:

var user = JSON.parse(localStorage.getItem('user'));
console.log(user.name);

3. Parsing null carelessly

If a key does not exist, getItem() returns null.

Safer pattern:

var raw = localStorage.getItem('user');
var user = raw ? JSON.parse(raw) : null;

4. Assuming JSON preserves everything

Broken expectation:

var data = {
  createdAt: new Date(),
  greet: function () {
    return 'hi';
  }
};

localStorage.setItem('data', JSON.stringify(data));

Issues:

  • greet is lost
  • createdAt becomes a string

5. Not handling invalid JSON

Broken code:

var value = JSON.parse(localStorage.getItem('settings'));

If stored data is malformed, this can throw.

Fix:

function getSettings() {
  try {
    var raw = localStorage.getItem('settings');
    return raw ? JSON.parse(raw) : {};
  } catch (e) {
    return {};
  }
}

6. Confusing localStorage and sessionStorage

  • localStorage persists across browser restarts
  • sessionStorage lasts only for the tab session

Choose the one that matches your data lifetime.

Comparisons

ConceptWhat it storesLifetimeBest for
localStorageStringsPersistent until clearedPreferences, cached state, carts
sessionStorageStringsUntil the tab/session endsTemporary UI state, one-session data
Plain object in memoryReal JavaScript valuesUntil page refreshRuntime data while app is open
CookiesSmall stringsConfigurable expirationServer communication, auth-related use cases

localStorage vs sessionStorage

localStorage.setItem('theme', 'dark');
sessionStorage.setItem('step', '2');
  • Use localStorage when data should remain after closing the browser.
  • Use sessionStorage when data should disappear after the tab closes.

Direct object storage vs JSON serialization

ApproachWorks?Result
setItem('x', obj)No, not as intendedStores "[object Object]"
setItem('x', JSON.stringify(obj))YesStores valid JSON text

JSON vs JavaScript object literal

They look similar, but they are not the same thing.

var obj = { one: 1 };              // JavaScript object
var json = '{"one":1}';           // JSON string
  • JavaScript object: usable directly in code
  • JSON string: text representation of data
Take Quiz

Cheat Sheet

// Save object
localStorage.setItem('key', JSON.stringify(obj));

// Load object
var obj = JSON.parse(localStorage.getItem('key'));

// Safe load with fallback
var raw = localStorage.getItem('key');
var obj = raw ? JSON.parse(raw) : null;

Rules

  • localStorage stores strings only
  • sessionStorage also stores strings only
  • Use JSON.stringify() before saving objects or arrays
  • Use JSON.parse() after reading JSON text
  • getItem() returns null if the key does not exist
  • JSON.parse() can throw on invalid JSON

Good patterns

function save(key, value) {
  localStorage.setItem(key, JSON.stringify(value));
}

function load(key, fallback) {
  try {
    var raw = localStorage.getItem(key);
    return raw ? JSON.parse(raw) : fallback;
  } catch (e) {
    return fallback;
  }
}

Edge cases

  • functions are not preserved
  • Date becomes a string
  • class instances lose methods
  • circular references cannot be stringified with normal JSON

Remove and clear

localStorage.removeItem('key');
localStorage.clear();

FAQ

Why does localStorage turn my object into [object Object]?

Because Web Storage stores strings. When you pass a plain object directly, JavaScript converts it to its default string form.

Can localStorage store JavaScript objects directly?

Not directly as true objects. You should serialize them with JSON.stringify() and restore them with JSON.parse().

Does sessionStorage behave the same way as localStorage?

Yes. Both store key-value pairs as strings.

Can I store arrays in localStorage?

Yes, but you should still use JSON:

localStorage.setItem('items', JSON.stringify([1, 2, 3]));

What happens if the key does not exist?

getItem() returns null.

Can JSON.stringify() store functions or methods?

No. Functions are not preserved in JSON.

Why does my Date come back as a string?

Because JSON has no native date type. You must convert it back manually if needed.

Is localStorage good for large or sensitive data?

No. It is best for small, non-sensitive browser data. It is not a secure storage mechanism for secrets.

Take Quiz

Mini Project

Description

Build a small browser-side preferences saver that stores a user's settings in localStorage. This project demonstrates the full save-and-load cycle for JavaScript objects using JSON, including fallback values and updating stored data.

Goal

Create a settings manager that saves, loads, updates, and clears a user preferences object from localStorage.

Requirements

  • Create a JavaScript object containing at least three user settings.
  • Save the object to localStorage using JSON.
  • Load the stored settings back into JavaScript and display at least one value.
  • Add a function that updates one setting and saves the object again.
  • Add a function that clears the saved settings.
Take Quiz

Keep learning

Related questions

View more