Note: Version 2.0 is a major release with a new middleware architecture. For v1.x documentation, see v1.3.4.
Vault Storage is a sophisticated browser-based storage library that leverages the power of IndexedDB, offering significant improvements over traditional LocalStorage. As a high-performance, asynchronous solution for client-side storage, it provides an intuitive and easy-to-use API similar to local and session storage, with extended capabilities through a powerful middleware system. It supports structured data, multiple stores, automatic expiration, encryption, validation, and event handling—all with a micro footprint.
- Similar API: Easy to use, similar to LocalStorage.
- Lightweight: No dependencies, tiny footprint
- ~1.5KB (minified + gzipped) - core Vault class
- ~3KB (minified + gzipped) - with EncryptedVault
- Modular architecture - only include what you need
- Middleware System: Extend functionality with composable middleware
- Encryption middleware for secure storage
- Validation middleware for data integrity
- Expiration middleware for automatic cleanup
- Custom middleware support
- EncryptedVault: Pre-configured vault with built-in encryption
- Multiple Stores Support: Supports multiple stores with single API
- Store Additional Meta Data: Store additional meta data along with the item value
- Automatic Expiration: Built-in TTL support with configurable cleanup strategies
- Event System: Listen to storage events (set, get, delete, clear)
- Backup and Restore: Export and import vault storage data
- Asynchronous: Non-blocking, asynchronous API
- Structured Data: Supports structured data, including objects and arrays
- TypeScript Support: Full TypeScript type definitions included
Install vault-storage using npm:
npm install vault-storage --saveOr using yarn:
yarn add vault-storageFirst, import the vault from vault-storage. The vault is a default instance
of the Vault storage class and hence does not need any special initialization
or setup!!! The vault provides a ready to use instance similar to localStorage
and sessionStorage. You can start using it right away without any setup.
import vault from 'vault-storage';Just start using it!
// Set the values.
vault.key1 = "value1";
vault.key2 = "value2";
// Get the values. Remember to use await! As it's asynchronous.
const value1 = await vault.key1; // "value1"
const value2 = await vault.key2; // "value2"You can also create a custom storage. This is useful when you want to use multiple storages for different purposes. All the custom storage also share the same API as the default vault storage and other built-in storages like localStorage and sessionStorage.
import Vault from 'vault-storage/vault';
const appStorage = new Vault("app-storage")
appStorage.setItem("key", "value")
console.log("key", await appStorage.getItem("key"))
const userStorage = new Vault("user-storage")
userStorage.setItem("key", "value")v2.0 introduces EncryptedVault - a pre-configured vault with encryption middleware.
This is the recommended approach for storing sensitive data.
import EncryptedVault from 'vault-storage/encrypted-vault';
// Create an encrypted vault with fixed credentials
const authStorage = new EncryptedVault({
password: "your-secret-password",
salt: "your-unique-salt",
});
// Usage is simple - encryption/decryption happens automatically
await authStorage.setItem("token", "sensitive-auth-token");
const token = await authStorage.getItem("token"); // Automatically decrypted
// -----
// Dynamic credentials based on key (more secure)
const authStorage = new EncryptedVault(async (key) => {
// Generate different credentials per key
const password = await derivePasswordForKey(key);
const salt = await deriveSaltForKey(key);
return { password, salt };
});
await authStorage.setItem("user-token", authToken);
const token = await authStorage.getItem("user-token");Security Best Practices:
- Use dynamic credentials (key-based) for better security
- Never hardcode credentials in production code
- Use asymmetric encryption for key transmission
- Generate credentials using Web Crypto API
- Fetch encrypted credentials from server and decrypt locally
- Use Content Security Policy (CSP) headers
- Always run in HTTPS (secure context)
- Rotate credentials periodically or use unique credentials per key
Vault v2.0 introduces a powerful middleware system that allows you to extend functionality in a composable way. Middleware can intercept and modify operations before and after execution.
import Vault from 'vault-storage/vault';
import { encryption } from 'vault-storage/middlewares';
const vault = new Vault('my-storage');
// Add encryption middleware
vault.use(encryption({
password: 'my-secret-password',
salt: 'my-salt'
}));
// All operations are now encrypted
await vault.setItem('secret', 'sensitive data');import Vault from 'vault-storage/vault';
import { validation } from 'vault-storage/middlewares';
const vault = new Vault('my-storage');
// Add validation middleware with custom validators
vault.use(validation(
// Validator 1: No admin keys
(context) => {
if (context.key?.startsWith('admin_')) {
throw new Error('Admin keys not allowed');
}
},
// Validator 2: Require object values
(context) => {
if (context.operation === 'set' && typeof context.value !== 'object') {
throw new Error('Only objects allowed');
}
}
));
await vault.setItem('user', { name: 'John' }); // ✓ Valid
await vault.setItem('admin_key', 'value'); // ✗ Throws errorimport Vault from 'vault-storage/vault';
import { expiration } from 'vault-storage/middlewares';
const vault = new Vault('my-storage');
// Add expiration middleware with proactive cleanup
vault.use(expiration({
cleanupStrategy: 'proactive',
cleanupInterval: 60000, // Clean every minute
}));
// Set item with TTL (time-to-live)
await vault.setItem('temp-data', 'value', {
ttl: 3600000 // Expires in 1 hour
});
// Or use absolute expiration
await vault.setItem('session', 'data', {
expires: Date.now() + 3600000
});
// Expired items are automatically removed and return null
setTimeout(async () => {
const value = await vault.getItem('temp-data'); // null if expired
}, 3700000);import Vault from 'vault-storage/vault';
import { encryption, validation, expiration } from 'vault-storage/middlewares';
const vault = new Vault('secure-storage');
// Chain multiple middlewares
vault
.use(validation((ctx) => {
if (!ctx.key) throw new Error('Key required');
}))
.use(encryption({ password: 'secret', salt: 'salt' }))
.use(expiration({ cleanupStrategy: 'background' }));
// All middlewares are applied in order
await vault.setItem('key', { data: 'value' }, { ttl: 3600000 });// Custom logging middleware
const loggingMiddleware = {
name: 'logging',
async beforeSet(context, next) {
console.log(`Setting ${context.key}:`, context.value);
await next();
},
async afterGet(context, next) {
const result = await next();
console.log(`Got ${context.key}:`, result);
return result;
}
};
vault.use(loggingMiddleware);Store data using the setItem method, indexer syntax, or dot notation:
// For set operation you can ignore await unless you want to wait for the
// operation to complete or you want to catch any errors.
vault.setItem('yourKey', { any: 'data' });
// Indexer syntax.
vault['yourKey'] = { any: 'data' };
// Dot notation.
vault.yourKey = { any: 'data' };Retrieve data using the getItem method, indexer syntax, or dot notation. For get
operations you must use await as it's asynchronous.
// Get the value using the getItem method.
const data = await vault.getItem('yourKey');
// Indexer syntax.
const data = await vault['yourKey'];
// Dot notation.
const data = await vault.yourKey;Remove data using the removeItem method:
// Remove the value using the remove method.
vault.removeItem('yourKey');
// Indexer syntax.
delete vault['yourKey'];
// Dot notation.
delete vault.yourKey;Clear all data from the store:
await vault.clear();Get the count of entries in the store:
const count = await vault.length();
console.log(count);Vault v2.0 includes a built-in event system that allows you to listen to storage changes.
import vault from 'vault-storage';
// Listen to all change events
vault.on('change', (event) => {
console.log(`Operation: ${event.operation}`);
console.log(`Key: ${event.key}`);
console.log(`Value:`, event.value);
});
// Listen to specific operations
vault.on('set', (event) => {
console.log(`Item set: ${event.key}`);
});
vault.on('delete', (event) => {
console.log(`Item deleted: ${event.key}`);
});
vault.on('clear', () => {
console.log('Vault cleared');
});
// Set an item - triggers 'set' and 'change' events
await vault.setItem('user', { name: 'John' });You can also store meta data along with the item value. The meta data is useful
when you want to store some additional information about the item. The meta data
is stored along with the item value and can be retrieved using the getItemMeta method.
// Set the additional meta data along with the item value.
vault.setItem('yourKey', { any: 'data' }, {
roles: ['editor', 'moderator'],
});
// Get the meta data for the specified item.
const meta = await vault.getItemMeta('yourKey');
console.log(`yourKey is marked for '${meta.roles}' roles! `);
if (user.roles.some(role => meta.roles.includes(role))) {
// User has access to the specified item in the vault.
}With version 1.3 and above, you can export and import the vault storage data. Please note that while exporting the secured storage data, the data is exported in non-encrypted form. You must be careful while exporting the data and ensure that the data is exported in a secure manner.
We are still considering the best way to export the secured storage data in an encrypted form. If you have any suggestions, please let us know.
import { importData, exportData } from 'vault-storage/backup';
const data = await exportData(vault);
// You can now save the data to a file or send it to the server.
// For example, you can save the data to a file using the following code.
const blob = new Blob([JSON.stringify(data)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url
a.download = 'vault-data.json';
a.click();
// To import the data back to the vault, you can use the following code.
const importedData = await importData(data);The Vault class is the foundation of the storage system, providing functionality similar to localStorage and sessionStorage with enhanced capabilities. It supports middleware, events, and advanced features.
import Vault from 'vault-storage/vault';Methods:
setItem(key: string, value: any, meta?: any): Store data in the storagegetItem(key: string): Retrieve data from the storageremoveItem(key: string): Remove data from the storageclear(): Clear all data from the storagelength(): Get the count of entries in the storagegetItemMeta(key: string): Get metadata for a specific itemuse(middleware): Add middleware to the vault (returnsthisfor chaining)on(event, callback): Listen to vault eventsoff(event, callback): Remove event listener
Pre-configured Vault with encryption middleware built-in. Recommended for storing sensitive data.
import EncryptedVault from 'vault-storage/encrypted-vault';
const vault = new EncryptedVault({
password: 'secret',
salt: 'salt'
});Inherits all methods from Vault class. All data is automatically encrypted/decrypted.
The vault is a default instance of the Vault class, providing a ready-to-use storage solution without any setup or initialization.
import vault from 'vault-storage';Middleware can be imported from vault-storage/middlewares:
import { encryption, validation, expiration } from 'vault-storage/middlewares';Available Middleware:
encryption(config, options?): Encrypts/decrypts data transparentlyvalidation(...validators): Validates operations with custom rulesexpiration(options?): Automatic expiration with configurable cleanup strategies
Cleanup Strategies for Expiration:
immediate: Check on every get operation (default)background: Background worker with periodic cleanuphybrid: Combines immediate checking with background cleanupproactive: Aggressive background cleanup with health monitoring
import { exportData, importData } from 'vault-storage/backup';exportData(vault: Vault): Export vault storage data (returns Promise)importData(vault: Vault, data: any): Import vault storage data (returns Promise)
Note: Encrypted data is exported in decrypted form. Handle with care.
| Feature | Vault v2.0 | LocalStorage |
|---|---|---|
| API Complexity | Simple, intuitive API | Simple, intuitive API |
| Capacity | Large (up to browser limit, often no less than 250MB) | Limited (5MB typical) |
| Multiple Stores | ✅ Supports multiple stores | ❌ Single store |
| Meta Data | ✅ Supports storing meta data | ❌ No meta data support |
| Encryption | ✅ Built-in EncryptedVault & middleware | ❌ No built-in encryption |
| Validation | ✅ Middleware-based validation | ❌ No validation |
| Auto-Expiration | ✅ TTL with multiple cleanup strategies | ❌ No expiration |
| Events | ✅ Built-in event system | ❌ No events (except storage event) |
| Middleware System | ✅ Extensible middleware architecture | ❌ Not applicable |
| Data Types | Supports rich types: objects, arrays, Date, Map, Set, TypedArrays, Blob, BigInt, etc. | Only stores strings |
| Backup/Restore | ✅ Built-in import/export | ❌ Manual implementation needed |
| Performance | Asynchronous, non-blocking | Synchronous, can block UI |
| TypeScript | ✅ Full type definitions | ✅ Basic types via @types/web |
| Bundle Size | ~1.5-3KB, modular | Native (0KB) |
Vault Storage v2.0 is feature-complete and production-ready with:
- Simple API - LocalStorage-like interface with async power
- Multiple Stores - Isolated storage instances
- Rich Data Types - Objects, arrays, Date, Map, Set, TypedArrays, Blob, BigInt, RegExp, and more
- Property Access - Dot notation and indexer syntax
- Metadata Support - Store additional info with any item
- Backup/Restore - Export and import vault data
- EncryptedVault - Pre-configured encrypted storage
- Encryption Middleware - Transparent encryption/decryption
- Validation Middleware - Custom data validation rules
- Dynamic Credentials - Key-based encryption credentials
- Auto-Expiration - TTL-based automatic cleanup
- Multiple Cleanup Strategies - Immediate, background, hybrid, proactive
- Event System - Listen to storage changes
- Metadata-Driven - Expiration, roles, custom properties
- Middleware Architecture - Composable, extensible functionality
- TypeScript Support - Full type definitions included
- Comprehensive Testing - 354+ tests passing
- Complete Documentation - API reference, guides, examples
- Tiny Bundle - ~1.5-3KB gzipped, modular design
- Zero Dependencies - No external packages required
- Asynchronous - Non-blocking operations
- Browser-Native - Leverages IndexedDB
- Middleware Pipeline - before/after/error hooks
- Event-Driven - Standard EventTarget API
Want to explore future possibilities? See Future Ideas for concepts being explored (not a committed roadmap).
- Documentation: Enhanced docs with real-world examples
-
SecuredVault → EncryptedVault
SecuredVaultclass has been removed in v2.0- Use
EncryptedVaultinstead - provides the same functionality with improved architecture
-
Module Exports
- Main export now uses ES modules
- Import paths have changed for better tree-shaking
-
Configuration Structure
- Constructor parameters have changed to separate encryption config from options
- See migration examples below
v1.x Code:
import SecuredVault from 'vault-storage/secured-vault';
const vault = new SecuredVault('my-storage', {
password: 'secret',
salt: 'salt'
});v2.0 Code:
import EncryptedVault from 'vault-storage/encrypted-vault';
const vault = new EncryptedVault({
password: 'secret',
salt: 'salt'
}, {
storageName: 'my-storage'
});Or use middleware approach:
import Vault from 'vault-storage/vault';
import { encryption } from 'vault-storage/middlewares';
const vault = new Vault('my-storage');
vault.use(encryption({ password: 'secret', salt: 'salt' }));- Middleware system for composable functionality
- Event system for reactive storage
- Auto-expiration with TTL support
- Validation middleware for data integrity
- Better TypeScript support with full type definitions
- Enhanced testing with 350+ test cases
Contributions to vault-storage are welcome. Please ensure that your code adheres to the existing style and includes tests covering new features or bug fixes.
vault-storage is MIT licensed.