Storage Adapters
Strata Storage provides multiple storage adapters to work across different platforms and use cases.
Adapter Overview
| Adapter | Platform | Persistence | Capacity | Performance | Best For |
|---|---|---|---|---|---|
| Memory | All | ❌ No | ~50MB | ⚡ Fast | Temporary data, caching |
| LocalStorage | Web | ✅ Yes | ~10MB | 🚀 Fast | Small persistent data |
| SessionStorage | Web | 🔄 Session | ~10MB | 🚀 Fast | Session data |
| IndexedDB | Web | ✅ Yes | ~1GB+ | ⚡ Fast | Large datasets |
| Cookies | Web | ✅ Yes | ~4KB | 🐌 Slow | Small server-shared data |
| Cache | Web | ✅ Yes | ~500MB+ | ⚡ Fast | Offline resources |
| URL | Web | ❌ No | ~2KB | 🚀 Fast | Shareable, reload-surviving UI state |
| Preferences | Mobile | ✅ Yes | ~1MB | 🚀 Fast | App settings |
| SQLite | iOS/Android | ✅ Yes | Unlimited | ⚡ Fast | Structured data, multi-store isolation (v2.6.0) |
| Secure | Mobile | ✅ Yes | ~5MB | 🔒 Secure | Sensitive data |
| Filesystem | iOS/Android | ✅ Yes | Device storage | 📁 Variable (file I/O) | Large or document-shaped values (v2.6.0: native backend added) |
Remote / sync adapters (opt-in)
These are not auto-selected; you register them explicitly (via
enableFirebaseSync) and target them with
{ storage: '...' }. firebase is an optional peer dependency.
| Adapter | Backend | Observable | Queryable | Best For |
|---|---|---|---|---|
firestore | Firebase Cloud Firestore | ✅ | ✅ | Cross-device/user document sync |
realtime | Firebase Realtime Database | ✅ | ❌ | Low-latency shared state |
Adapter Selection
Strata automatically selects the best available adapter based on:
- Platform - Web, iOS, Android, or Node.js
- Availability - Whether the adapter is supported
- Configuration - Your specified preferences
- Strategy - Performance, reliability, or capacity first
Automatic Selection
// Strata will automatically choose the best adapter
const storage = new Strata();
await storage.initialize();
// Will use IndexedDB on web, SQLite on mobile
await storage.set('data', largeObject);
Manual Selection
// Force specific storage adapter
await storage.set('data', value, {
storage: 'localStorage'
});
// Try multiple adapters in order
await storage.set('data', value, {
storage: ['secure', 'preferences', 'memory']
});
Adapter Capabilities
Each adapter has different capabilities:
interface StorageCapabilities {
persistent: boolean; // Survives across sessions
synchronous: boolean; // Supports synchronous operations
observable: boolean; // Supports subscriptions/watching
transactional: boolean; // Supports transactions
queryable: boolean; // Supports querying
maxSize: number; // Maximum storage size (bytes, -1 for unlimited)
binary: boolean; // Supports binary data
encrypted: boolean; // Supports encryption
crossTab: boolean; // Cross-tab/window support
}
Checking Capabilities
// Get capabilities for a specific adapter
const capabilities = storage.getCapabilities('indexedDB');
console.log('Supports transactions:', capabilities.transactional);
// Get all adapter capabilities
const allCapabilities = storage.getCapabilities();
Web Adapters
Memory Adapter
- In-memory storage using Map
- Fastest performance
- No persistence
- Perfect for temporary data
LocalStorage Adapter
- Browser's localStorage API
- Synchronous operations
- ~10MB capacity
- Domain-specific persistence
SessionStorage Adapter
- Browser's sessionStorage API
- Session-based persistence
- ~10MB capacity
- Tab-specific storage
IndexedDB Adapter
- Browser's IndexedDB API
- Asynchronous operations
- Large capacity (GB+)
- Supports transactions and indexes
Cookie Adapter
- HTTP cookies
- Server-accessible
- ~4KB per cookie
- Cross-subdomain support
Cache Adapter
- Service Worker Cache API
- Network request caching
- Large capacity
- Offline support
URL Adapter
- Stores state in the page URL (query or hash)
- Synchronous; emits change events on navigation
- Shareable and reload-surviving
- For small UI state only (~2KB), browser-only, not durable
Mobile Adapters (Capacitor)
Preferences Adapter
- Native preferences APIs
- UserDefaults (iOS) / SharedPreferences (Android)
- Key-value storage
- App settings and small data
SQLite Adapter
- SQLite database on iOS (SQLite3) and Android (SQLiteDatabase)
- Full SQL support; complex queries and indexed fields
- Multi-store (v2.6.0):
databaseandtableoptions now route to distinct physical database files/tables on iOS and Android; separatedefineStorageinstances with differentdatabase/tablevalues are fully isolated size(true)returns{ keys, values, metadata }byte breakdown (v2.6.0)- Full
StorageValuewrapper (TTL, tags, metadata) round-trips correctly through nativeget/set(fixed in v2.6.0) - Pending on-device verification for v2.6.0 changes; see device-verification guide
Secure Adapter
- Keychain (iOS) / EncryptedSharedPreferences (Android)
- Hardware-backed encryption
- Biometric protection support
- Sensitive data storage
Filesystem Adapter
- Native file system (iOS
NSDocumentsDirectory, AndroidgetFilesDir()) - One JSON file per key under
strata_storage/, atomic writes via staging rename isAvailable()returnstrueon iOS/Android;falsein browsersize(true)returns{ keys, values, metadata }byte breakdown- v2.6.0: native backend added — previously unavailable on all platforms
- Pending on-device verification; see device-verification guide
Custom Adapters
You can create custom adapters by extending the BaseAdapter:
import { BaseAdapter, StorageValue, StorageCapabilities } from 'strata-storage';
export class CustomAdapter extends BaseAdapter {
readonly name = 'custom' as const;
readonly capabilities: StorageCapabilities = {
persistent: true,
synchronous: false,
observable: true,
transactional: false,
queryable: false,
maxSize: -1,
binary: false,
encrypted: false,
crossTab: false
};
async initialize(config?: unknown): Promise<void> {
// Initialize your adapter
}
async isAvailable(): Promise<boolean> {
// Check if adapter can be used
return true;
}
async get<T>(key: string): Promise<StorageValue<T> | null> {
// Implement get logic
}
async set<T>(key: string, value: StorageValue<T>): Promise<void> {
// Implement set logic
}
// ... implement other required methods
}
Registering Custom Adapter
import { AdapterRegistry } from 'strata-storage';
const registry = new AdapterRegistry();
registry.register(new CustomAdapter());
Adapter-Specific Configuration
Each adapter can have specific configuration:
const storage = new Strata({
adapters: {
indexedDB: {
name: 'MyAppDB',
version: 1,
stores: ['data', 'cache']
},
localStorage: {
prefix: 'myapp_'
},
cookies: {
domain: '.example.com',
secure: true
},
sqlite: {
database: 'app.db',
version: '1.0'
}
}
});
Performance Comparison
| Operation | Memory | LocalStorage | IndexedDB | SQLite |
|---|---|---|---|---|
| Write 1KB | <1ms | 2-5ms | 5-10ms | 5-15ms |
| Read 1KB | <1ms | 1-2ms | 5-10ms | 5-15ms |
| Write 1MB | 1ms | 20-50ms | 10-20ms | 20-30ms |
| Read 1MB | <1ms | 10-20ms | 10-20ms | 15-25ms |
| Query 1000 items | 1-2ms | N/A | 10-20ms | 5-10ms |
Storage Limits
| Adapter | Limit per Item | Total Limit | Notes |
|---|---|---|---|
| Memory | No limit | ~50-100MB | Limited by available RAM |
| LocalStorage | No limit | ~10MB | Varies by browser |
| SessionStorage | No limit | ~10MB | Per tab/window |
| IndexedDB | No limit | 50%+ disk | Browser specific |
| Cookies | 4KB | 50 cookies | Per domain |
| Cache | No limit | Varies | Based on available space |
| Preferences | 1MB | ~5MB | Platform specific |
| SQLite | No limit | Unlimited | Limited by device storage |
| Secure | 5KB | ~5MB | Platform specific |
| Filesystem | No limit | Unlimited | Limited by device storage |
Best Practices
1. Choose the Right Adapter
// User preferences - use secure storage
await storage.set('apiKey', key, { storage: 'secure' });
// Large datasets - use IndexedDB or SQLite
await storage.set('dataset', data, { storage: ['sqlite', 'indexedDB'] });
// Temporary data - use memory
await storage.set('cache', data, { storage: 'memory' });
// Session data - use sessionStorage
await storage.set('session', data, { storage: 'sessionStorage' });
2. Handle Adapter Failures
// Fallback chain
const fallbackStorages: StorageType[] = ['indexedDB', 'localStorage', 'memory'];
try {
await storage.set('data', value, { storage: fallbackStorages });
} catch (error) {
console.error('All storage adapters failed');
}
3. Optimize for Platform
// Platform-specific optimization
const storage = new Strata({
defaultStorages: isWeb()
? ['indexedDB', 'localStorage']
: ['sqlite', 'preferences']
});
Next Steps
- Learn about specific Web Adapters
- Explore Mobile Adapters
- Read about Creating Custom Adapters