Configuration
Strata Storage provides extensive configuration options to customize behavior for your specific needs.
Configuration Overview
import { Strata } from 'strata-storage';
const storage = new Strata({
// Platform detection (auto-detected by default)
platform: 'web', // 'web' | 'ios' | 'android' | 'node'
// Default storage types in order of preference
defaultStorages: ['indexedDB', 'localStorage', 'memory'],
// Storage adapter specific configurations
adapters: {
indexedDB: {
dbName: 'MyAppDB',
version: 1
},
localStorage: {
prefix: 'myapp_'
},
cookies: {
secure: true,
sameSite: 'strict'
}
},
// Encryption settings
encryption: {
enabled: false,
password: 'your-secure-password',
algorithm: 'AES-GCM',
keyLength: 256,
keyDerivation: 'PBKDF2'
},
// Compression settings
compression: {
enabled: false,
algorithm: 'lz', // the only supported algorithm
threshold: 1024 // bytes
},
// Synchronization settings
sync: {
enabled: false,
storages: ['localStorage'],
conflictResolution: 'latest'
},
// Time-to-live settings
ttl: {
defaultTTL: 3600000, // 1 hour (ms)
cleanupInterval: 60000, // 1 minute
autoCleanup: true
}
});
Configuration Options
Platform
Strata automatically detects the platform, but you can override it:
const storage = new Strata({
platform: 'ios' // Force iOS behavior
});
Options:
'web'- Browser environment'ios'- iOS native (Capacitor)'android'- Android native (Capacitor)'node'- Node.js environment
Default Storages
Specify storage preference order. Strata will use the first available:
const storage = new Strata({
defaultStorages: ['sqlite', 'preferences', 'memory']
});
Web Options:
'memory'- In-memory storage'localStorage'- Browser localStorage'sessionStorage'- Browser sessionStorage'indexedDB'- IndexedDB database'cookies'- HTTP cookies'cache'- Cache API
Mobile Options:
'preferences'- Native preferences (UserDefaults/SharedPreferences)'sqlite'- SQLite database'secure'- Keychain (iOS) / EncryptedSharedPreferences (Android)'filesystem'- File system storage
Adapter Configuration
IndexedDB
adapters: {
indexedDB: {
dbName: 'MyDatabase', // Database name
version: 1 // Database version
}
}
LocalStorage/SessionStorage
adapters: {
localStorage: {
prefix: 'app_' // Key prefix
}
}
Cookies
adapters: {
cookies: {
secure: true, // HTTPS only
sameSite: 'lax' // 'strict' | 'lax' | 'none'
}
}
SQLite (Mobile)
adapters: {
sqlite: {
filename: 'app.db' // Database file name
}
}
The native SQLite backend also accepts per-call
database/tableoptions (passed toget/set/etc.) to address multiple physical stores — see the SQLite adapter reference.
Encryption Configuration
encryption: {
enabled: true, // Enable/disable encryption
password: 'secret', // Encryption password
algorithm: 'AES-GCM', // 'AES-GCM' | 'AES-CBC'
keyLength: 256, // 128 | 192 | 256
keyDerivation: 'PBKDF2', // PBKDF2
iterations: 600000, // PBKDF2 iterations (default: 600000, OWASP)
saltLength: 16 // Salt length in bytes
}
Compression Configuration
compression: {
enabled: true, // Enable/disable compression
algorithm: 'lz', // only the bundled zero-dependency LZ codec is supported
threshold: 1024 // Min size to compress (bytes)
}
Sync Configuration
sync: {
enabled: true, // Enable cross-tab sync
storages: ['localStorage'], // Storages to sync (cross-tab fallback is localStorage-only)
interval: 5000, // Optional periodic sync interval (ms)
conflictResolution: 'latest' // 'latest' | 'merge' | custom function
}
Cross-tab sync uses
BroadcastChannelwhen available and falls back tostorageevents. Browsers only fire cross-tabstorageevents forlocalStorage;sessionStorageis tab-scoped and never propagates cross-tab.
TTL Configuration
ttl: {
defaultTTL: 3600000, // Default TTL in ms (1 hour)
cleanupInterval: 60000, // Cleanup sweep interval (ms)
autoCleanup: true, // Auto-remove expired items
batchSize: 100, // Max items removed per cleanup cycle
slidingTTL: false, // Reset TTL on access (instance default)
onExpire: (keys) => {} // Callback invoked with expired keys
}
Environment-Specific Configuration
Development
const devConfig = {
encryption: { enabled: false }, // Disable for debugging
compression: { enabled: false },
sync: {
enabled: true,
interval: 0 // 0 = event-driven (no polling)
}
};
Production
const prodConfig = {
encryption: {
enabled: true,
password: process.env.STORAGE_KEY
},
compression: {
enabled: true,
threshold: 512 // Aggressive compression
},
ttl: {
autoCleanup: true,
cleanupInterval: 300000 // 5 minutes
}
};
Storage Selection
Strata does not use named "strategies." Instead, list the storage backends you
want in defaultStorages, in order of preference — Strata uses the first one
available on the current platform:
const storage = new Strata({
// Try persistent stores first, fall back to memory as a last resort
defaultStorages: ['indexedDB', 'localStorage', 'memory']
});
defaultStorages is not a registration listIt is the preference order for choosing the default adapter, and the fallback order when one is
unusable. Operations with no explicit storage — keys(), clear(), size(), subscribe() —
deliberately span every registered adapter, so listing one storage here does not stop the others from
being registered or swept.
To leave an adapter out entirely, say so:
const storage = defineStorage({
defaultStorages: ['localStorage'],
adapters: { sessionStorage: false, indexedDB: false, cookies: false, cache: false },
});
Since 2.9.0, adapters: { <name>: false } skips registration, not just initialization. (Before 2.9.0
it only skipped initialization, so the adapter was still registered and still swept — which is what made
defaultStorages look like a registration list that was being ignored.)
Key prefix and the 3.0.0 migration
Since 3.0.0, localStorage and sessionStorage keys are written under strata:
(DEFAULT_WEB_KEY_PREFIX, exported). Existing data migrates itself on read.
const storage = defineStorage(); // keys at `strata:<key>`
const legacy = defineStorage({ keyPrefix: false }); // pre-3.0, bare keys
const custom = defineStorage({ keyPrefix: 'myapp:' }); // your own
const noMove = defineStorage({ migrateLegacyKeys: false }); // don't adopt 2.x entries
keyPrefix: false when something outside this library reads a physical keyA pre-paint theme script that runs before any module loads, or a logger reading its own level, knows the exact key name — and a prefix changes it underneath them. Migration keeps the data reachable through this library; it cannot fix a hard-coded reader.
How migration works. A miss at strata:<key> falls back to the bare <key>; if the value is one of
ours it is moved under the prefix and returned. It is per key, on read — never a bulk sweep, which
would adopt every unprefixed envelope on the origin including keys belonging to an instance that opted out
or a sibling app still on 2.x. It never adopts a non-envelope, and it never overwrites a value
already at the prefixed key. keys() lists not-yet-migrated entries so enumeration stays complete, but
listing never moves anything.
Unchanged: cookies (already strata_), indexedDB and cache (named stores), memory (its own Map),
url (already prefixes its params). namespace is a separate mechanism — the physical key is
<keyPrefix><namespace>:<key>.
Shared storage areas and key ownership
localStorage, sessionStorage and cookies are shared with every other script on the origin, and the
web adapters' key prefix is empty by default. Since 2.9.0 an adapter identifies its own data by shape
— a key is its own only when the stored value is a StorageValue envelope — so keys(), the TTL sweep
and clear() never touch data this library did not write.
Consequences worth knowing:
- A key written to the same area by anything else is invisible to
keys()by design. - A value we cannot read is skipped and reported at
debug, not as an error: it is evidence the key belongs to somebody else, which is the ordinary case in a shared area. setLogLevel('debug')(exported) names every skipped key and why.
Setting namespace or a per-adapter prefix is still worth doing for a clean keyspace. It is no longer
what keeps this library off other applications' keys.
Custom Configuration Patterns
Multi-Instance Configuration
// User data storage
const userStorage = new Strata({
defaultStorages: ['secure', 'preferences'],
encryption: { enabled: true }
});
// Cache storage
const cacheStorage = new Strata({
defaultStorages: ['cache', 'indexedDB'],
ttl: { defaultTTL: 300000 } // 5 minutes
});
// Temporary storage
const tempStorage = new Strata({
defaultStorages: ['memory', 'sessionStorage'],
ttl: { defaultTTL: 60000 } // 1 minute
});
Feature Flags
const storage = new Strata({
// Enable features based on environment
encryption: {
enabled: process.env.NODE_ENV === 'production'
},
compression: {
enabled: !navigator.connection?.saveData
},
sync: {
enabled: 'BroadcastChannel' in window
}
});
Validation
Strata validates configuration at initialization:
try {
const storage = new Strata({
encryption: {
enabled: true
// Missing required 'password'
}
});
await storage.initialize();
} catch (error) {
console.error('Invalid configuration:', error);
}
Next Steps
- Explore Storage Adapters
- Learn about Encryption
- Read about Caching Patterns