npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@sldm/storage

v0.3.0

Published

Unified storage abstraction for localStorage, sessionStorage, IndexedDB, and databases

Downloads

18

Readme

@sldm/storage

Unified storage abstraction for localStorage, sessionStorage, IndexedDB, and databases

A lightweight, type-safe storage abstraction layer that provides a consistent API across different storage backends. Perfect for web applications that need flexible storage options with a unified interface.

Features

  • Unified API: Same interface for all storage types
  • Type-safe: Full TypeScript support with generics
  • Multiple backends: localStorage, sessionStorage, in-memory, and more
  • Prefix support: Namespace your keys to avoid conflicts
  • Auto-serialization: Automatic JSON serialization/deserialization
  • SSR-friendly: Memory storage for server-side rendering
  • Zero dependencies: Core package has no runtime dependencies
  • Fully tested: 100% test coverage with TDD approach

Installation

npm install @sldm/storage
# or
pnpm add @sldm/storage
# or
yarn add @sldm/storage

Quick Start

import { createStorage } from '@sldm/storage';

// Create a storage instance
const storage = createStorage('local'); // or 'session', 'memory'

// Store values
storage.set('user', { name: 'John', age: 30 });
storage.set('token', 'abc123');

// Retrieve values
const user = storage.get('user'); // { name: 'John', age: 30 }
const token = storage.get('token'); // 'abc123'

// Check if key exists
if (storage.has('user')) {
  console.log('User data found');
}

// Remove a key
storage.remove('token');

// Clear all keys
storage.clear();

// Get all keys
const keys = storage.keys(); // ['user']

Storage Types

LocalStorage

import { LocalStorageAdapter } from '@sldm/storage';

const storage = new LocalStorageAdapter();
storage.set('key', 'value');

SessionStorage

import { SessionStorageAdapter } from '@sldm/storage';

const storage = new SessionStorageAdapter();
storage.set('key', 'value');

Memory Storage

Perfect for testing or SSR environments:

import { MemoryStorageAdapter } from '@sldm/storage';

const storage = new MemoryStorageAdapter();
storage.set('key', 'value');

Using the Factory

The factory automatically falls back to memory storage if the requested storage is unavailable:

import { createStorage } from '@sldm/storage';

// Automatically falls back to memory storage on server
const storage = createStorage('local');

Advanced Usage

Type Safety

interface User {
  name: string;
  age: number;
  email: string;
}

const storage = createStorage('local');

// Type-safe storage
storage.set<User>('user', { name: 'John', age: 30, email: '[email protected]' });

// Type-safe retrieval
const user = storage.get<User>('user');
// user is typed as User | null

Prefixed Keys

Avoid key conflicts by using prefixes:

import { LocalStorageAdapter } from '@sldm/storage';

// App-specific storage
const appStorage = new LocalStorageAdapter('myapp:');
appStorage.set('user', { name: 'John' });
// Stores as 'myapp:user' in localStorage

// Component-specific storage
const componentStorage = new LocalStorageAdapter('myapp:component:');
componentStorage.set('state', { count: 0 });
// Stores as 'myapp:component:state'

// Clear only clears prefixed keys
appStorage.clear(); // Only clears 'myapp:*' keys

Complex Data Types

Automatically handles serialization:

const storage = createStorage('local');

// Objects
storage.set('config', {
  theme: 'dark',
  notifications: true,
  settings: {
    fontSize: 16,
    language: 'en'
  }
});

// Arrays
storage.set('items', [1, 2, 3, 4, 5]);

// Nested structures
storage.set('data', {
  users: [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' }
  ],
  metadata: {
    total: 2,
    page: 1
  }
});

API Reference

IStorage Interface

All storage adapters implement this interface:

interface IStorage {
  get<T = any>(key: string): T | null;
  set<T = any>(key: string, value: T): void;
  remove(key: string): void;
  clear(): void;
  has(key: string): boolean;
  keys(): string[];
}

Methods

get<T>(key: string): T | null

Retrieve a value from storage. Returns null if the key doesn't exist.

const value = storage.get('key');
const user = storage.get<User>('user');

set<T>(key: string, value: T): void

Store a value. Automatically serializes to JSON.

storage.set('key', 'value');
storage.set('user', { name: 'John' });

Note: Setting a value to undefined will remove the key.

remove(key: string): void

Remove a key from storage.

storage.remove('key');

clear(): void

Remove all keys from storage. If a prefix is set, only removes prefixed keys.

storage.clear();

has(key: string): boolean

Check if a key exists in storage.

if (storage.has('user')) {
  // Key exists
}

keys(): string[]

Get all keys in storage. Returns full keys including prefix if set.

const allKeys = storage.keys();

createStorage(type, prefix?)

Factory function to create storage instances with automatic fallback.

function createStorage(
  type: 'local' | 'session' | 'memory' | 'indexeddb',
  prefix?: string
): IStorage

Parameters:

  • type: Storage type to create
  • prefix: Optional prefix for all keys

Returns: Storage instance implementing IStorage

Use Cases

User Preferences

const preferences = createStorage('local', 'prefs:');

preferences.set('theme', 'dark');
preferences.set('language', 'en');
preferences.set('notifications', true);

Session Management

const session = createStorage('session', 'auth:');

session.set('token', 'eyJhbGc...');
session.set('user', { id: 1, name: 'John' });
session.set('expiresAt', Date.now() + 3600000);

Shopping Cart

const cart = createStorage('local', 'cart:');

interface CartItem {
  id: number;
  name: string;
  quantity: number;
  price: number;
}

const items = cart.get<CartItem[]>('items') || [];
items.push({ id: 1, name: 'Product', quantity: 1, price: 29.99 });
cart.set('items', items);

Form State Persistence

const formStorage = createStorage('session', 'form:checkout:');

// Auto-save form data
formStorage.set('step1', {
  email: '[email protected]',
  name: 'John Doe'
});

// Restore on page reload
const savedData = formStorage.get('step1');

Error Handling

The storage adapters handle errors gracefully:

const storage = createStorage('local');

// Circular references throw an error
const obj: any = { name: 'test' };
obj.self = obj;

try {
  storage.set('circular', obj);
} catch (error) {
  console.error('Failed to serialize:', error);
}

Browser Support

  • localStorage: All modern browsers
  • sessionStorage: All modern browsers
  • MemoryStorage: Works everywhere (Node.js, browsers, SSR)

Coming Soon

  • IndexedDB adapter: For large data storage
  • Database adapters: SQL and NoSQL database support
  • Async API: Promise-based API for async storage backends
  • Encryption: Built-in encryption support
  • Compression: Automatic compression for large values
  • Expiration: TTL support for automatic cleanup

License

MIT © Matthias Kluth

Links