Working with localStorage or sessionStorage in JavaScript is a common task when working with web applications. In this note, we’ll look at how to set, get, and remove items from localStorage or sessionStorage using JavaScript.

Here is a simple utility function that creates a storage helper for localStorage or sessionStorage in JavaScript or TypeScript. This helper provides methods to set, get, and remove items from the storage.

Creating a Storage Helper

Following is a simple utility function that creates a storage helper for encode or decode a JSON values

// helpers/json.ts
function encodeValue(value: string | number | object | boolean | [] | Date) {
  if (typeof value === 'string') {
    return value
  }

  return JSON.stringify(value)
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function decodeValue<T = any>(value: string) {
  if (typeof value !== 'string') {
    throw new TypeError('The given value is not of type `string`')
  }

  try {
    return JSON.parse(value) as T
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error)
    throw new Error(`Could not decode: ${message}`)
  }
}

A createStorage function that takes a StorageLike object and returns a storage helper with set, get, and remove methods.

import { encodeValue, decodeValue } from './helpers/json'

interface StorageLike {
  getItem(key: string): string | null
  setItem(key: string, value: string): void
  removeItem(key: string): void
}

type JsonValue = string | number | object | boolean | [] | Date
interface StorageValue<T = JsonValue> {
  value: T
  expiry?: number
}

const createStorage = (storage: StorageLike) => {
  const set = (key: string, value: JsonValue, { ttl }: { ttl?: number } = {}) => {
    const now = new Date()

    const expiry = ttl ? now.getTime() + ttl : undefined

    storage.setItem(key, encodeValue({ value, expiry }))
  }

  const get = <T>(key: string) => {
    const value = storage.getItem(key)

    if (!value) return

    const decodedValue = decodeValue<Partial<StorageValue<T>>>(value)

    if (!decodedValue?.value) return

    if (decodedValue.expiry) {
      const now = new Date()

      // compare the expiry time of the item with the current time
      if (now.getTime() > decodedValue.expiry) {
        storage.removeItem(key)
        return
      }
    }

    return decodedValue.value
  }

  const remove = (key: string) => storage.removeItem(key)

  return {
    set,
    get,
    remove,
  }
}

Usage example

In this example, we create a storage helper for localStorage and sessionStorage using the createStorage function. We then use the set method to store a string value and an object value with a time-to-live (TTL) of 1 second. We use the get method to retrieve the stored values and demonstrate that the object value is removed after the TTL expires.

import { createStorage } from './storage'

// Create a storage helper for localStorage
const localStorage = createStorage(window.localStorage)

// or for sessionStorage
const sessionStorage = createStorage(window.sessionStorage)

// Set a string value in localStorage
localStorage.set('name', 'Alice')

console.log(localStorage.get('name')) // Output: 'Alice'

localStorage.set('user', { id: 1, name: 'Alice' }, { ttl: 1000 })

setTimeout(() => {
  console.log(localStorage.get('user')) // Output: undefined
}, 2000)