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

@sitharaj08/react-unified-storage

v1.0.1

Published

One unified, secure, and modern storage solution for React.

Readme

@sitharaj08/react-unified-storage

npm version License: Apache 2.0 TypeScript

React bindings for unified storage - One unified, secure, and modern storage solution for React applications.

✨ Features

  • React hooks with automatic re-rendering
  • 🚀 TypeScript-first with strict typing and generics
  • 🔒 End-to-end encryption with AES-GCM and PBKDF2
  • 📦 Automatic compression with gzip
  • 🔄 Cross-tab synchronization via BroadcastChannel API
  • 💾 Multiple storage drivers (IndexedDB, localStorage, sessionStorage, memory)
  • 🛡️ SSR-safe with automatic fallback to in-memory storage
  • 📋 Schema validation with Zod integration
  • TTL support for automatic data expiration
  • 🔄 Versioning & migrations for data evolution
  • 📊 Metadata tracking (timestamps, driver info, versions)
  • 🎯 Tiny bundle (<10KB gzipped)
  • 🧪 Comprehensive testing with Vitest

📦 Installation

# React package (includes everything)
npm install @sitharaj08/react-unified-storage

# Peer dependencies
npm install react@^16.8.0

🚀 Quick Start

import { StorageProvider, useStore } from '@sitharaj08/react-unified-storage';

function App() {
  return (
    <StorageProvider config={{ driver: 'auto' }}>
      <UserProfile />
    </StorageProvider>
  );
}

function UserProfile() {
  const [user, setUser] = useStore('user', {
    defaultValue: { name: 'Anonymous', theme: 'light' }
  });

  return (
    <div>
      <h1>Welcome, {user.name}!</h1>
      <button onClick={() => setUser({ ...user, theme: 'dark' })}>
        Toggle Theme
      </button>
    </div>
  );
}

🏗️ Architecture

This package provides React bindings for the core storage functionality. It includes:

  • StorageProvider - Context provider for configuration
  • useStore - Hook for individual key-value storage
  • useStoreSuspense - Suspense-enabled version of useStore
  • useCollection - Hook for collection-based storage

📚 API Reference

StorageProvider

<StorageProvider config={config}>
  <App />
</StorageProvider>

Configuration Options:

interface StorageConfig {
  driver?: StorageDriver;
  namespace?: string;
  broadcast?: boolean;
  encryption?: {
    key: string;
    salt?: string;
  };
  compression?: boolean;
  errorHandler?: (error: Error) => void;
}

useStore

const [value, setValue, meta] = useStore<T>(key, options?);

Parameters:

  • key: string - Storage key
  • options?: UseStoreOptions<T>

Returns:

  • value: T - Current stored value
  • setValue: (value: T) => Promise<void> - Update function
  • meta?: StorageMeta - Metadata (when metadata: true)

Options:

interface UseStoreOptions<T> {
  defaultValue?: T;
  schema?: z.ZodSchema<T>;
  version?: number;
  metadata?: boolean;
  ttlMs?: number;
}

useStoreSuspense

Suspense-enabled version of useStore:

const [value, setValue] = useStoreSuspense<T>(key, options);

useCollection

const collection = useCollection<T>(name, options?);

Returns a collection instance with CRUD operations:

await collection.add({ id: 1, name: 'Item' });
const items = await collection.list();
await collection.update(1, { name: 'Updated' });
await collection.remove(1);

🏗️ Storage Drivers

| Driver | Description | SSR Safe | Persistence | Size Limit | Best For | |--------|-------------|----------|-------------|------------|----------| | auto | Auto-selects best available | ✅ | ✅ | Varies | General use | | idb | IndexedDB | ❌ | ✅ | ~50MB+ | Large datasets | | local | localStorage | ❌ | ✅ | ~5-10MB | Small data | | session | sessionStorage | ❌ | Tab-only | ~5-10MB | Temporary data | | memory | In-memory | ✅ | Tab-only | Unlimited | SSR/Caching |

🔧 Advanced Usage

Encryption Setup

<StorageProvider config={{
  encryption: {
    key: 'your-32-character-secret-key-here!',
    salt: 'optional-salt-for-key-derivation'
  }
}}>
  <App />
</StorageProvider>

Schema Validation & Migrations

import { z } from 'zod';

const userSchemaV1 = z.object({
  name: z.string(),
  email: z.string()
});

const userSchemaV2 = z.object({
  name: z.string(),
  email: z.string(),
  avatar: z.string().optional()
});

const [user, setUser] = useStore('user', {
  schema: userSchemaV2,
  version: 2,
  // Migration function (if needed)
  migrate: (oldData, oldVersion) => {
    if (oldVersion === 1) {
      return { ...oldData, avatar: undefined };
    }
    return oldData;
  }
});

Cross-Tab Synchronization

// Automatic synchronization (enabled by default with broadcast: true)
<StorageProvider config={{ broadcast: true }}>
  <App />
</StorageProvider>

TTL (Time To Live)

// Expires in 1 hour
const [data, setData] = useStore('temp-token', {
  ttlMs: 60 * 60 * 1000
});

Error Handling

<StorageProvider config={{
  errorHandler: (error) => {
    console.error('Storage error:', error);
    // Send to error reporting service
  }
}}>
  <App />
</StorageProvider>

🌐 SSR & Server-Side Rendering

The library automatically detects SSR environments and falls back to memory storage:

// This works in both SSR and client environments
<StorageProvider config={{ driver: 'auto' }}>
  <App />
</StorageProvider>

SSR Behavior:

  • Server: Uses memory storage (no persistence)
  • Client: Hydrates to chosen driver (IndexedDB/localStorage)
  • Data consistency: Server and client data are isolated

🧪 Testing

import { setup, read, write } from '@sitharaj08/react-unified-storage-core';
import { MemoryDriver } from '@sitharaj08/react-unified-storage-core';

// Use memory driver for testing
setup({ driver: 'memory' });

// Your tests here
test('should store and retrieve data', async () => {
  await write('test', { value: 42 });
  const result = await read('test');
  expect(result).toEqual({ value: 42 });
});

📊 Performance

  • Bundle Size: <10KB gzipped (includes core functionality)
  • Operations: ~1-2ms for localStorage, ~5-10ms for IndexedDB
  • Memory Usage: Minimal overhead, efficient data structures
  • Compression: Up to 70% size reduction for text data

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

Apache License 2.0 © Sitharaj Seenivasan