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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@amitkhare/indexed-storage

v1.2.0

Published

A modern, localStorage-like API for IndexedDB with instance-based and static APIs, multi-store support, configurable databases, and enhanced capabilities

Downloads

364

Readme

@amitkhare/indexed-storage

A modern, localStorage-like API for IndexedDB that provides a simple and intuitive interface for client-side data storage with enhanced capabilities.

✨ Features

  • localStorage-like API - Familiar setItem(), getItem(), removeItem() interface
  • Type Preservation - Stores and retrieves exact values (primitives, objects, arrays)
  • Async/Await Support - Modern Promise-based API
  • Configurable Database - Customize database name, version, and store name
  • Multi-Store Support - Multiple object stores within the same database
  • Multiple Database Instances - Create separate databases for different purposes
  • Store-Specific APIs - Isolated access to individual stores
  • Batch Operations - Get/set/remove multiple items at once
  • Optional Logging - Configurable console logging for debugging (disabled by default)
  • TypeScript Ready - Complete TypeScript declarations included
  • Environment-Aware - Easy configuration for development, staging, and production

🚀 Installation

npm install @amitkhare/indexed-storage

Import

IndexedStorage supports multiple import patterns for maximum flexibility:

// Default import
import IndexedStorage from '@amitkhare/indexed-storage';

// Named import  
import { IndexedStorage } from '@amitkhare/indexed-storage';

// Import with utilities
import IndexedStorage, { useStorageManager, useIndexedDB } from '@amitkhare/indexed-storage';

// Named import with utilities
import { IndexedStorage, useStorageManager, useIndexedDB } from '@amitkhare/indexed-storage';

// TypeScript type imports
import { IndexedStorage, type IndexedStorageConfig } from '@amitkhare/indexed-storage';

Basic Usage

// Store data
await IndexedStorage.setItem('username', 'john_doe');
await IndexedStorage.setItem('count', 42);
await IndexedStorage.setItem('user', { name: 'John', age: 30 });

// Retrieve data
const username = await IndexedStorage.getItem('username'); // 'john_doe'
const count = await IndexedStorage.getItem('count'); // 42
const user = await IndexedStorage.getItem('user'); // { name: 'John', age: 30 }

// Check if item exists
if (await IndexedStorage.hasItem('username')) {
  console.log('Username is stored');
}

// Remove item
await IndexedStorage.removeItem('username');

// Clear all data
await IndexedStorage.clear();

🔥 New Instance-based API

NEW: Create multiple independent IndexedStorage instances with different configurations!

Multiple Independent Instances

// Create separate storage instances for different purposes
const appStorage = new IndexedStorage({
    dbName: 'MyApp',
    storeName: 'settings',
    logging: true
});

const userStorage = new IndexedStorage({
    dbName: 'UserData',  
    storeName: 'profiles'
});

const cacheStorage = new IndexedStorage({
    dbName: 'Cache',
    storeName: 'temp'
});

// Each instance operates independently
await appStorage.setItem('theme', 'dark');
await userStorage.setItem('currentUser', { id: 123, name: 'John' });
await cacheStorage.setItem('lastSync', Date.now());

Instance Configuration Options

const storage = new IndexedStorage({
    dbName: 'MyDatabase',        // Database name (default: 'IndexedStorage')
    version: 1,                  // Database version (default: 1)
    storeName: 'myStore',        // Default store name (default: 'data')
    storeConfig: {               // Store configuration
        keyPath: 'id',           // Key path for the store
        autoIncrement: true      // Auto-increment keys
    },
    logging: true                // Enable logging (default: false)
});

Multi-Store within Single Database

// Method 1: Create stores during initialization
const storage = new IndexedStorage({
    dbName: 'ECommerceApp',
    storeName: 'products', // default store
    additionalStores: ['users', 'orders', 'cart'], // create these stores automatically
    storeConfigs: {
        users: { keyPath: 'id', autoIncrement: true },
        orders: { keyPath: 'orderId', autoIncrement: false },
        cart: { keyPath: null, autoIncrement: false }
    }
});

// Method 2: Create stores dynamically
const storage2 = new IndexedStorage({
    dbName: 'MyApp',
    storeName: 'default'
});

await storage2.createStore('users', { keyPath: 'id', autoIncrement: true });
await storage2.createStore('sessions', { keyPath: 'sessionId' });

// Store data in different stores
await storage.setItem('prod1', { name: 'Laptop', price: 999 }, 'products');
await storage.setItem('user1', { name: 'John', email: '[email protected]' }, 'users');
await storage.setItem('order1', { total: 999, items: ['prod1'] }, 'orders');

// Get store-specific API for easier operations
const userStore = storage.getStore('users');
const orderStore = storage.getStore('orders');

await userStore.setItem('user2', { name: 'Jane', email: '[email protected]' });
await orderStore.setItem('order2', { total: 1500, items: ['prod1', 'prod2'] });

// Batch operations across multiple stores
await storage.setMultipleStores({
    products: { 'prod2': { name: 'Mouse', price: 29 } },
    users: { 'user3': { name: 'Bob', email: '[email protected]' } }
});

// Get data from multiple stores
const multiData = await storage.getMultipleStores({
    products: ['prod1', 'prod2'],
    users: ['user1', 'user2']
});

// List all stores
const stores = await storage.listStores();
console.log(stores); // ['products', 'users', 'orders', 'cart']

// Get all data from all stores
const allData = await storage.getAllStoresData();
console.log(allData); // { products: {...}, users: {...}, orders: {...}, cart: {...} }

Instance Methods

Core Operations:

  • setItem(key, value, storeName?) - Store an item
  • getItem(key, storeName?) - Retrieve an item
  • removeItem(key, storeName?) - Remove an item
  • clear(storeName?) - Clear all items from a store

Batch Operations:

  • getAllKeys(storeName?) - Get all keys
  • getAllValues(storeName?) - Get all values

Store Management:

  • createStore(name, config?) - Create new store
  • deleteStore(name) - Delete a store
  • listStores() - List all stores
  • getStoreInfo(name?) - Get store information
  • getAvailableStores() - Get available stores (alias for listStores)

Multi-Store Operations:

  • getStore(storeName) - Get store-specific API object
  • getAllStoresData() - Get data from all stores
  • clearAllStores() - Clear all stores in database
  • setMultipleStores(storeData) - Set data across multiple stores
  • getMultipleStores(storeKeys) - Get data from multiple stores

Database Management:

  • init() - Initialize the database connection
  • close() - Close the database connection

Backward Compatibility

The original static API still works alongside the new instance API:

// Static API (legacy) - still works
await IndexedStorage.setItem('key', 'value');

// Instance API (new)
const storage = new IndexedStorage({ dbName: 'MyApp' });
await storage.setItem('key', 'value');

📖 See Instance API Guide for comprehensive examples and migration guide.

⚙️ Configuration

Enable/Disable Logging

By default, IndexedStorage operates silently. You can enable logging for debugging:

// Enable logging for debugging (disabled by default)
IndexedStorage.configure({ enableLogging: true });

// Disable logging
IndexedStorage.configure({ enableLogging: false });

// Check current configuration
const config = IndexedStorage.getConfig();
console.log(config); // { enableLogging: false }

🗄️ Configurable Database Settings

IndexedStorage now supports configurable IndexedDB settings, allowing you to customize the database name, version, and store name for different applications and use cases.

Basic Database Configuration

// Configure custom database settings
IndexedStorage.configure({
  enableLogging: true,
  indexedDB: {
    dbName: 'MyApplication',        // Database name (default: 'LocalStorageDB')
    dbVersion: 2,                   // Database version (default: 1)
    storeName: 'appData'            // Object store name (default: 'localStates')
  }
});

// All subsequent operations use the custom configuration
await IndexedStorage.setItem('user-data', { name: 'John' });

Multiple Database Instances

Create separate database instances for different purposes:

import { useIndexedDB, useStorageManager } from '@amitkhare/indexed-storage';

// User data database
const userDB = useIndexedDB({
  dbName: 'UserData',
  dbVersion: 1,
  storeName: 'users'
});

// Application cache database
const cacheDB = useIndexedDB({
  dbName: 'AppCache',
  dbVersion: 1,
  storeName: 'cache'
});

// Store data in different databases
await userDB.save('profile', { name: 'John', email: '[email protected]' });
await cacheDB.save('api-data', { response: {...}, timestamp: Date.now() });

Multi-Store Configuration

Use multiple object stores within the same database:

// Configure with multiple stores in the same database
IndexedStorage.configure({
  enableLogging: true,
  indexedDB: {
    dbName: 'MyApplication',
    dbVersion: 1,
    storeName: 'users',                           // Primary store
    additionalStores: ['cache', 'analytics', 'settings'] // Additional stores
  }
});

// Get store-specific APIs
const userStore = IndexedStorage.getStore('users');
const cacheStore = IndexedStorage.getStore('cache');
const analyticsStore = IndexedStorage.getStore('analytics');

// Use each store independently
await userStore.setItem('profile', { name: 'John' });
await cacheStore.setItem('api-data', { response: 'cached' });
await analyticsStore.setItem('event-1', { action: 'click' });

Environment-Specific Configuration

const isDevelopment = process.env.NODE_ENV === 'development';

IndexedStorage.configure({
  enableLogging: isDevelopment,
  indexedDB: {
    dbName: isDevelopment ? 'MyApp_Development' : 'MyApp_Production',
    dbVersion: isDevelopment ? 1 : 2,
    storeName: 'appData'
  }
});

📖 See Configurable Database Guide for comprehensive examples and best practices.

📖 See Multi-Store Usage Example for comprehensive multi-store examples.

📖 See Migration Guide for upgrading to multi-store functionality.

📚 API Reference

Core Methods

getItem(key)

Retrieves an item from storage.

  • Returns: The stored value or null if not found

setItem(key, value)

Stores an item in storage.

  • Supports: All JSON-serializable data types

removeItem(key)

Removes an item from storage.

hasItem(key)

Checks if an item exists in storage.

  • Returns: true if the key exists

clear()

Removes all items from storage.

getAllKeys()

Gets all keys from storage.

  • Returns: Array of all keys

length()

Gets the number of items in storage.

Batch Operations

getMultiple(keys)

Retrieves multiple items at once.

const data = await IndexedStorage.getMultiple(['user', 'settings']);
// Returns: { user: {...}, settings: {...} }

setMultiple(items)

Stores multiple items at once.

await IndexedStorage.setMultiple({
  'user': { name: 'John' },
  'settings': { theme: 'dark' }
});

removeMultiple(keys)

Removes multiple items at once.

await IndexedStorage.removeMultiple(['temp1', 'temp2']);

Multi-Store Operations

getStore(storeName)

Get a store-specific API for working with a particular store.

const cacheStore = IndexedStorage.getStore('cache');
await cacheStore.setItem('key', 'value');
const value = await cacheStore.getItem('key');

getAvailableStores()

Get list of all available stores in the database.

const stores = IndexedStorage.getAvailableStores();
console.log(stores); // ['users', 'cache', 'analytics', 'settings']

getAllStoresData()

Get all data from all stores at once.

const allData = await IndexedStorage.getAllStoresData();
// Returns: { users: [...], cache: [...], analytics: [...] }

clearAllStores()

Clear all data from all stores.

await IndexedStorage.clearAllStores();

🎯 Usage Examples

Application State

// Save application state
await IndexedStorage.setItem('app-state', {
  currentView: 'dashboard',
  sidebarCollapsed: true,
  activeProject: 'project-123'
});

// Restore state on reload
const appState = await IndexedStorage.getItem('app-state');
if (appState) {
  navigateToView(appState.currentView);
  setSidebarState(appState.sidebarCollapsed);
}

User Preferences

// Save user preferences
await IndexedStorage.setItem('user-preferences', {
  theme: 'dark',
  language: 'en',
  notifications: true
});

// Load preferences on app start
const prefs = await IndexedStorage.getItem('user-preferences');
if (prefs) {
  applyTheme(prefs.theme);
  setLanguage(prefs.language);
}

Caching Data

// Cache API responses
await IndexedStorage.setItem('api-cache-users', {
  data: usersData,
  timestamp: Date.now(),
  expires: Date.now() + (1000 * 60 * 60) // 1 hour
});

// Check cache before API call
const cachedUsers = await IndexedStorage.getItem('api-cache-users');
if (cachedUsers && Date.now() < cachedUsers.expires) {
  return cachedUsers.data;
}

Multi-Store Application

// Configure multi-store database
IndexedStorage.configure({
  indexedDB: {
    dbName: 'TodoApp',
    dbVersion: 1,
    storeName: 'todos',
    additionalStores: ['cache', 'analytics', 'settings']
  }
});

// Use different stores for different purposes
const todoStore = IndexedStorage.getStore('todos');
const cacheStore = IndexedStorage.getStore('cache');
const analyticsStore = IndexedStorage.getStore('analytics');
const settingsStore = IndexedStorage.getStore('settings');

// Store todos
await todoStore.setItem('todo-1', {
  title: 'Buy groceries',
  completed: false,
  createdAt: new Date().toISOString()
});

// Cache API response
await cacheStore.setItem('/api/weather', {
  data: { temperature: 22, condition: 'sunny' },
  timestamp: Date.now(),
  ttl: 300000 // 5 minutes
});

// Track user events
await analyticsStore.setItem('event-' + Date.now(), {
  action: 'todo-created',
  timestamp: Date.now(),
  userAgent: navigator.userAgent
});

// Save app settings
await settingsStore.setItem('app-config', {
  theme: 'dark',
  notifications: true,
  autoSave: true
});

// Get data from all stores
const allData = await IndexedStorage.getAllStoresData();
console.log('All stores data:', allData);

🔧 Error Handling

IndexedStorage includes comprehensive error handling:

try {
  await IndexedStorage.setItem('large-data', massiveObject);
} catch (error) {
  console.error('Failed to store data:', error);
  // Handle storage quota exceeded, etc.
}

// Check availability before using
if (await IndexedStorage.isAvailable()) {
  // Safe to proceed
} else {
  // Fallback to localStorage or other storage
}

🔄 Migration from localStorage

IndexedStorage is designed as a drop-in replacement for localStorage with async operations:

// localStorage (synchronous)
localStorage.setItem('key', JSON.stringify(data));
const data = JSON.parse(localStorage.getItem('key') || '{}');

// IndexedStorage (asynchronous)
await IndexedStorage.setItem('key', data);
const data = await IndexedStorage.getItem('key');

📄 License

MIT License - see LICENSE file for details.

🤝 Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.