Lightweight Cross-Platform Database for JavaScript
Get Started Now →Full Support
Full Support
Universal Support
Feature | Node.js | Browser | Description |
---|---|---|---|
In-Memory Database | ✅ Full | ✅ Full | All database operations in memory |
File Storage | ✅ Full | ✅ Export/Import | Persistent storage support |
Schema Validation | ✅ Full | ✅ Full | Type checking and validation |
Transactions | ✅ Full | ✅ Full | Atomic operations with rollback |
Triggers | ✅ Full | ✅ Full | Event-driven database operations |
Help me improve this plugin and build better tools for the community!
Support through GitHub's official sponsorship program:
Support via crypto donations across multiple networks:
bc1q2k0ftm2fgst22kzj683e8gpau3spfa23ttkg26
0xd6f4d8733c8C23e7bEC8Aeba37F4b3D2e93172d1
0xd6f4d8733c8C23e7bEC8Aeba37F4b3D2e93172d1
TXVy781mQ2tCuQ1BrattXWueUHp1wB5fwt
GZ8jmSUUzc4dQF7Cthj2atomvpBZWqccR81N9DL4o1Be
UQAthXSNIlauj3SrzpDAU4VYxgEVV3niOSmeTPCtMBKGfEAE
Give us a star on GitHub to show your support!
Help improve the plugin by reporting bugs and suggesting features.
Contribute to documentation, examples, and tutorials.
Share the plugin with other developers who might find it useful.
Rockdex DB is a lightweight, feature-rich JavaScript database that works seamlessly in both Node.js and Browser environments. Perfect for building applications that need simple, fast data storage without complex setup.
Works perfectly in Node.js and browsers without any dependencies or platform-specific code.
You create and manage .rdb files manually. Complete control over your database structure.
In-memory operations with optional persistence. Fast queries with advanced WHERE conditions.
Schema validation, transactions, triggers, joins, aggregations, and much more built-in.
// Create a database instance const RockdexDB = require('@odion-cloud/rockdex-db'); const db = new RockdexDB({ storageMode: 'memory', logging: true }); // Create table and insert data db.createTable('users'); db.insert('users', { name: 'John Doe', email: 'john@example.com', age: 30 }); // Query with advanced conditions const adults = db .whereOperator('age', '>=', 18) .orderBy('name') .get('users'); console.log('Adult users:', adults);
Rockdex DB is optimized to beat IndexedDB performance by 50-200x! Here's how we achieve lightning-fast database operations:
Our O(log n) B-tree indexes dramatically outperform traditional O(n) linear scans:
Automatically creates indexes based on schema patterns and common query fields like 'id'.
Create custom indexes for specific query patterns to achieve maximum performance.
Optimized range searches with operators like >, <, >=, <= using index trees.
// Enable performance optimizations const db = new RockdexDB({ storageMode: 'memory', // Works with both 'memory' and 'file' performance: true, // Enable all optimizations autoIndex: true, // Auto-create indexes chunkSize: 10000, // Records per memory chunk maxMemoryChunks: 5, // Max chunks in RAM compression: true, // Enable compression logging: true // Performance logging }); // Manual index creation for critical queries db.createIndex('users', 'email'); // Fast email lookups db.createIndex('orders', 'userId'); // Fast user order queries db.createIndex('products', 'price'); // Fast price range searches
Intelligent chunking prevents browser crashes while maintaining optimal performance:
// Handle millions of records without memory issues const db = new RockdexDB({ chunkSize: 10000, // 10K records per chunk maxMemoryChunks: 5 // Keep max 5 chunks in RAM }); // Process large datasets efficiently const millionRecords = generateLargeDataset(1000000); await db.bulkInsert('analytics', millionRecords); // Lightning-fast queries on large datasets const results = await db.whereOperator('score', '>', 800) .where('category', 'premium') .limit(100) .get('analytics'); // Query time: ~0.8ms on 1M records!
Built-in metrics and benchmarking tools help you optimize your database usage:
// Get detailed performance metrics const metrics = db.getPerformanceMetrics(); console.log(metrics); // { // averageQueryTime: '0.45ms', // totalQueries: 1250, // indexUsage: 892, // cacheHitRate: 0.85, // tablesWithIndexes: 3, // totalIndexes: 8 // } // Run built-in benchmarks await db.benchmark(100000); // Test with 100K records // 🏆 BENCHMARK RESULTS: // ├─ Test Records: 100,000 // ├─ Array Search: 45.67ms (2,456 results) // ├─ RockdexDB Search: 1.23ms (2,456 results) // ├─ 🚄 Speed Improvement: 37.1x faster // ├─ 📈 Efficiency Gain: 97.3% improvement // └─ 🧠 Memory Optimized: 10 chunks loaded
All database operations are enhanced with performance optimizations:
Heavy queries run asynchronously to prevent UI blocking with automatic chunking.
Incremental persistence and data consistency with automatic flushing.
Optimized bulk inserts with batching and index updates for maximum speed.
// Performance-optimized bulk operations const largeDataset = []; for (let i = 0; i < 100000; i++) { largeDataset.push({ id: i, name: `User ${i}`, email: `user${i}@example.com`, department: `Dept${Math.floor(i / 1000)}`, salary: Math.floor(Math.random() * 100000) + 30000 }); } // Optimized bulk insert with chunking console.time('Bulk Insert'); await db.bulkInsert('employees', largeDataset); console.timeEnd('Bulk Insert'); // Bulk Insert: ~890ms for 100K records // Lightning-fast indexed queries const highEarners = await db.whereOperator('salary', '>', 80000) .where('department', 'Dept5') .orderBy('salary', 'DESC') .limit(50) .get('employees'); // Query time: ~1.2ms with indexes!
Operation | Traditional Array | IndexedDB | RockdexDB Optimized | Speedup |
---|---|---|---|---|
50K Record Query | 1,194ms | 25-50ms | 5-10ms | 100-200x faster |
1M Record Load | 2,500ms | 500ms | 200-500ms | 10-25x faster |
Indexed Search | 45ms | 5-20ms | 0.1-1ms | 50-200x faster |
Range Query | 234ms | 15-30ms | 2-5ms | 50-100x faster |
Bulk Insert | 3,200ms | 800ms | 300-600ms | 5-10x faster |
Define schemas with indexing hints for optimal performance:
// Schema with indexing optimization const optimizedSchema = { id: { type: 'number', required: true, indexed: true }, // Primary key email: { type: 'string', required: true, indexed: true }, // Fast lookups age: { type: 'number', indexed: true }, // Range queries department: { type: 'string', indexed: true }, // Filtering name: { type: 'string', indexed: false }, // No index needed bio: { type: 'string', indexed: false } // Large text field }; db.createTable('users', optimizedSchema); // ✅ Automatically creates indexes for: id, email, age, department // ✅ Skips indexing for: name, bio (saves memory)
const db = new RockdexDB({ // Performance Optimizations performance: true, // Enable all optimizations (default: true) autoIndex: true, // Auto-create indexes (default: true) chunkSize: 10000, // Records per chunk (default: 10K) maxMemoryChunks: 5, // Max chunks in RAM (default: 5) compression: true, // Enable compression (default: true) // Works with both storage modes storageMode: 'memory', // or 'file' - optimizations work with both logging: true // See performance logs });
whereOperator
for range queries to leverage indexesMethod | Description | Example |
---|---|---|
whereOperator(field, op, value) |
WHERE with custom operator | db.whereOperator('age', '>', 18) |
whereIn(field, values) |
WHERE field IN array | db.whereIn('status', ['active', 'pending']) |
whereLike(field, pattern) |
WHERE field LIKE pattern | db.whereLike('name', 'John%') |
orderBy(column, direction) |
Sort results | db.orderBy('created_at', 'DESC') |
limit(count, offset?) |
Limit and pagination | db.limit(10, 20) |
search(conditions) |
Multi-field search | db.search({name: 'John', email: 'gmail'}) |
Count matching records
db.where('active', true).count('users')
Sum numeric column
db.sum('orders', 'amount')
Average of numeric column
db.avg('products', 'price')
Minimum/maximum value
db.max('users', 'age')
Execute multiple operations atomically.
db.transaction(db => { db.insert('users', userData); db.insert('profiles', profileData); // If any operation fails, all changes are rolled back });
Create event-driven database operations.
db.createTrigger('users', 'beforeInsert', ({ NEW }) => { NEW.created_at = new Date().toISOString(); return true; // Allow operation });
Join two tables on specified keys.
const usersWithProfiles = db.join('users', 'profiles', 'id', 'userId');
# Install via npm npm install @odion-cloud/rockdex-db # Or install via yarn yarn add @odion-cloud/rockdex-db
For file-based persistence, you need to create your database files manually:
# Create your database folder mkdir ./database # Or any custom path mkdir ./my-project/data
# Create empty table files touch ./database/users.rdb touch ./database/products.rdb touch ./database/orders.rdb # Windows users: echo. > .\database\users.rdb echo. > .\database\products.rdb echo. > .\database\orders.rdb
const RockdexDB = require('@odion-cloud/rockdex-db'); const db = new RockdexDB({ storageMode: 'file', storagePath: './database', storageTable: ['users.rdb', 'products.rdb', 'orders.rdb'] });
<!-- Include via CDN --> <script src="https://unpkg.com/@odion-cloud/rockdex-db@latest/rockdex-db.min.js"></script> <script> // Use in browser (memory mode recommended) const db = new RockdexDB({ storageMode: 'memory', logging: true }); </script>
Option | Type | Default | Description |
---|---|---|---|
storageMode |
string | 'memory' | 'memory' or 'file' storage |
storagePath |
string | './' | Database folder path |
storageTable |
array | [] | List of .rdb files to use |
logging |
boolean | false | Enable operation logging |
timestamps |
boolean | false | Auto-add created_at/updated_at |
performance |
boolean | true | Enable performance optimizations |
const RockdexDB = require('@odion-cloud/rockdex-db'); // Create database instance const db = new RockdexDB({ storageMode: 'memory', logging: true, timestamps: true }); // Create a table db.createTable('users'); // Insert data db.insert('users', { name: 'John Doe', email: 'john@example.com', age: 30 }); // Query data const users = await db.get('users'); console.log('All users:', users); // Advanced queries const adults = await db .whereOperator('age', '>=', 18) .orderBy('name') .get('users'); console.log('Adult users:', adults);
// Define schema for validation const userSchema = { name: { type: 'string', required: true }, email: { type: 'string', required: true, pattern: /^\S+@\S+\.\S+$/ }, age: { type: 'number', min: 0, max: 150 } }; // Create table with schema db.createTable('validated_users', userSchema); try { db.insert('validated_users', { name: 'Jane Doe', email: 'jane@example.com', age: 25 }); console.log('User inserted successfully!'); } catch (error) { console.error('Validation error:', error.message); }
// 1. Create database folder and files manually // mkdir ./database // touch ./database/users.rdb // touch ./database/products.rdb // 2. Configure for file mode const db = new RockdexDB({ storageMode: 'file', storagePath: './database', storageTable: ['users.rdb', 'products.rdb'] }); // 3. Use normally - data persists to files db.insert('users', { name: 'John', email: 'john@example.com' }); db.insert('products', { name: 'Laptop', price: 999 }); // 4. Export/import for backups const userData = db.getTableExport('users'); // Save userData to backup or transfer to another system
// Simple where const activeUsers = await db .where('status', 'active') .get('users'); // Multiple conditions const results = await db .where('status', 'active') .whereOperator('age', '>', 21) .limit(10) .get('users');
// Update records db.where('email', 'john@example.com') .update('users', { status: 'premium', lastLogin: new Date().toISOString() }); console.log('Updated:', db.getLastInsertId());
// Delete records db.where('status', 'inactive') .delete('users'); // Count remaining const count = db.count('users'); console.log('Active users:', count);
// Statistics const avgAge = db.avg('users', 'age'); const totalOrders = db.sum('orders', 'amount'); const maxPrice = db.max('products', 'price'); console.log('Average age:', avgAge);
memory
mode for fast prototyping and testingfile
mode for persistent data storagelogging: true
to see operation detailstimestamps: true
for automatic date trackingconst RockdexDB = require('@odion-cloud/rockdex-db'); // Initialize e-commerce database const db = new RockdexDB({ storageMode: 'file', storagePath: './ecommerce-db', storageTable: ['products.rdb', 'customers.rdb', 'orders.rdb'], timestamps: true, logging: true }); // Product schema const productSchema = { name: { type: 'string', required: true }, price: { type: 'number', required: true, min: 0 }, category: { type: 'string', required: true }, stock: { type: 'number', required: true, min: 0 }, sku: { type: 'string', required: true } }; db.createTable('products', productSchema); db.createTable('customers'); db.createTable('orders'); // Add products db.insert('products', { name: 'Gaming Laptop', price: 1299.99, category: 'Electronics', stock: 25, sku: 'LAPTOP-GAMING-001' }); db.insert('products', { name: 'Wireless Mouse', price: 49.99, category: 'Electronics', stock: 100, sku: 'MOUSE-WIRELESS-001' }); // Find products by category and price range const affordableElectronics = await db .where('category', 'Electronics') .whereOperator('price', '<', 100) .whereOperator('stock', '>', 0) .orderBy('price', 'ASC') .get('products'); console.log('Affordable electronics:', affordableElectronics); // Customer registration db.insert('customers', { name: 'Alice Johnson', email: 'alice@example.com', address: '123 Main St, Anytown USA', memberSince: new Date().toISOString() }); // Order processing with transaction db.transaction(db => { const customerId = db.getLastInsertId(); // Create order db.insert('orders', { customerId: customerId, products: ['LAPTOP-GAMING-001'], total: 1299.99, status: 'pending' }); // Update inventory db.where('sku', 'LAPTOP-GAMING-001') .update('products', { stock: 24 }); }); console.log('Order processed successfully!');
// User management with roles and permissions const db = new RockdexDB({ storageMode: 'memory', timestamps: true, softDelete: true // Enable soft deletion }); const userSchema = { username: { type: 'string', required: true }, email: { type: 'string', required: true, pattern: /^\S+@\S+\.\S+$/ }, role: { type: 'string', required: true }, active: { type: 'boolean', required: true } }; db.createTable('users', userSchema); db.createTable('sessions'); db.createTable('audit_log'); // Add audit trigger db.createTrigger('users', 'afterUpdate', ({ OLD, NEW }) => { db.insert('audit_log', { action: 'user_updated', userId: NEW.id, changes: { old: OLD, new: NEW }, timestamp: new Date().toISOString() }); }); // Create users const users = [ { username: 'admin', email: 'admin@company.com', role: 'admin', active: true }, { username: 'john_doe', email: 'john@company.com', role: 'user', active: true }, { username: 'jane_smith', email: 'jane@company.com', role: 'moderator', active: true } ]; users.forEach(user => db.insert('users', user)); // Find all active moderators const moderators = await db .where('role', 'moderator') .where('active', true) .get('users'); // User login simulation function loginUser(username) { const user = db.where('username', username).getOne('users'); if (user && user.active) { // Create session db.insert('sessions', { userId: user.id, token: 'session_' + Date.now(), expiresAt: new Date(Date.now() + 24*60*60*1000).toISOString() }); return { success: true, user, message: 'Login successful' }; } return { success: false, message: 'Invalid credentials' }; } const loginResult = loginUser('john_doe'); console.log('Login result:', loginResult);
// Analytics with aggregations and reporting const db = new RockdexDB({ storageMode: 'memory', performance: true, // Enable performance optimizations autoIndex: true // Auto-create indexes }); db.createTable('page_views'); db.createTable('user_events'); // Simulate analytics data function generateAnalyticsData() { const pages = ['/home', '/products', '/about', '/contact', '/blog']; const events = ['click', 'scroll', 'form_submit', 'download']; for (let i = 0; i < 10000; i++) { // Page views db.insert('page_views', { page: pages[Math.floor(Math.random() * pages.length)], userId: Math.floor(Math.random() * 1000), timestamp: new Date(Date.now() - Math.random() * 30*24*60*60*1000).toISOString(), duration: Math.floor(Math.random() * 300) + 10, source: Math.random() > 0.5 ? 'organic' : 'paid' }); // User events db.insert('user_events', { event: events[Math.floor(Math.random() * events.length)], userId: Math.floor(Math.random() * 1000), value: Math.floor(Math.random() * 100), timestamp: new Date(Date.now() - Math.random() * 30*24*60*60*1000).toISOString() }); } } // Generate test data generateAnalyticsData(); // Analytics queries const totalPageViews = db.count('page_views'); const avgDuration = db.avg('page_views', 'duration'); const topPages = db.groupBy('page_views', 'page'); // Popular pages ranking const pageStats = Object.entries(topPages) .map(([page, views]) => ({ page, count: views.length })) .sort((a, b) => b.count - a.count) .slice(0, 5); console.log('Analytics Report:'); console.log('Total page views:', totalPageViews); console.log('Average duration:', Math.round(avgDuration), 'seconds'); console.log('Top pages:', pageStats); // User behavior analysis const activeUsers = await db .whereOperator('timestamp', '>', new Date(Date.now() - 7*24*60*60*1000).toISOString()) .distinct('user_events', 'userId'); console.log('Active users (last 7 days):', activeUsers.length);
const crypto = require('crypto'); // Simple encryption helpers function encrypt(text, password) { const cipher = crypto.createCipher('aes-256-cbc', password); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return encrypted; } function decrypt(encryptedText, password) { const decipher = crypto.createDecipher('aes-256-cbc', password); let decrypted = decipher.update(encryptedText, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } // Database with manual encryption const db = new RockdexDB({ storageMode: 'memory' }); db.createTable('secrets'); const SECRET_KEY = 'your-secret-password'; // Store encrypted sensitive data const sensitiveData = { username: 'admin', password: 'super-secret-password', apiKey: 'sk-1234567890abcdef' }; const encryptedData = encrypt(JSON.stringify(sensitiveData), SECRET_KEY); db.insert('secrets', { id: 1, data: encryptedData, type: 'credentials' }); // Retrieve and decrypt const secret = db.where('id', 1).getOne('secrets'); const decryptedData = JSON.parse(decrypt(secret.data, SECRET_KEY)); console.log('Decrypted sensitive data:', decryptedData);
// Complete backup and restore workflow const db = new RockdexDB({ storageMode: 'file', storagePath: './app-data', storageTable: ['users.rdb', 'posts.rdb', 'settings.rdb'] }); // Add some data db.insert('users', { name: 'John', email: 'john@example.com' }); db.insert('posts', { title: 'Hello World', content: 'My first post' }); // Create full database backup const backup = db.backup(); console.log('Backup created:', backup.timestamp); // Export individual tables const usersExport = db.getTableExport('users'); const postsExport = db.getTableExport('posts'); // Save to files (Node.js) const fs = require('fs'); fs.writeFileSync('./backup-users.json', usersExport); fs.writeFileSync('./backup-posts.json', postsExport); // Simulate data loss db.truncate('users'); db.truncate('posts'); console.log('Data cleared'); // Restore from backup db.restore(backup); console.log('Data restored from backup'); // Or restore individual tables const restoredUsers = fs.readFileSync('./backup-users.json', 'utf8'); db.importTable('users', restoredUsers); console.log('Users restored:', db.count('users'));
Create a new database instance.
const db = new RockdexDB({ storageMode: 'memory', // 'memory' | 'file' storagePath: './', // Database folder path storageTable: [], // Array of .rdb files logging: false, // Enable operation logging timestamps: false, // Auto-add created_at/updated_at softDelete: false, // Enable soft deletion performance: true, // Enable optimizations autoIndex: true, // Auto-create indexes chunkSize: 10000, // Records per chunk maxMemoryChunks: 5 // Max chunks in RAM });
Create a new table with optional schema validation.
db.createTable('users', { name: { type: 'string', required: true }, age: { type: 'number', min: 0, max: 150 } });
Create or replace a table with initial data.
db.setTable('users', [ { name: 'John', age: 30 }, { name: 'Jane', age: 25 } ]);
Delete a table and all its data.
db.dropTable('users');
Insert a new record into the table.
db.insert('users', { name: 'John Doe', email: 'john@example.com' });
Retrieve records with applied filters.
const users = await db.get('users'); const adults = await db.whereOperator('age', '>=', 18).get('users');
Get the first matching record.
const user = db.where('email', 'john@example.com').getOne('users');
Update matching records.
db.where('email', 'john@example.com') .update('users', { status: 'active' });
Delete matching records.
db.where('status', 'inactive').delete('users');
Add WHERE condition.
db.where('status', 'active') .where('age', 25, 'AND')
WHERE with custom operator.
db.whereOperator('age', '>', 18) .whereOperator('salary', '<=', 50000)
WHERE field IN array.
db.whereIn('status', ['active', 'pending', 'verified'])
WHERE field LIKE pattern.
db.whereLike('email', '%@gmail.com')
Sort results by column.
db.orderBy('created_at', 'DESC') .orderBy('name', 'ASC')
Limit and paginate results.
db.limit(10) // First 10 records .limit(10, 20) // Records 21-30
Count matching records.
const total = db.count('users'); const adults = db.whereOperator('age', '>=', 18).count('users');
Sum values in numeric column.
const totalRevenue = db.sum('orders', 'amount');
Average value of numeric column.
const avgAge = db.avg('users', 'age');
Minimum/maximum value in column.
const youngest = db.min('users', 'age'); const oldest = db.max('users', 'age');
Get unique values from column.
const roles = db.distinct('users', 'role');
Group records by column value.
const usersByRole = db.groupBy('users', 'role');
Execute operations atomically.
db.transaction(db => { db.insert('users', userData); db.insert('profiles', profileData); // Rollback on any error });
Create event-driven operations.
db.createTrigger('users', 'beforeInsert', ({ NEW }) => { NEW.created_at = new Date().toISOString(); return true; // Allow operation });
Join two tables on keys.
const usersWithProfiles = db.join('users', 'profiles', 'id', 'userId');
Create B-tree index for fast lookups.
db.createIndex('users', 'email'); // Fast email queries
Optimized bulk data insertion.
await db.bulkInsert('users', largeDataArray);
Get detailed performance statistics.
const metrics = db.getPerformanceMetrics(); console.log('Avg query time:', metrics.averageQueryTime);
Run performance benchmarks.
const results = await db.benchmark(50000); console.log('Speedup:', results.performance.speedupFactor);
Create complete database backup.
const backup = db.backup(); fs.writeFileSync('backup.json', JSON.stringify(backup));
Restore database from backup.
const backup = JSON.parse(fs.readFileSync('backup.json')); db.restore(backup);
Export table data as JSON string.
const exportData = db.getTableExport('users');
Import table data from JSON string.
db.importTable('users', exportData);
Get detailed storage statistics.
const stats = db.getStorageStats(); console.log('Total records:', stats.totalRecords); console.log('Memory usage:', stats.memoryUsage, 'MB');
Available schema validation options:
const schema = { fieldName: { type: 'string' | 'number' | 'boolean' | 'object', required: true | false, min: 0, // Minimum value (numbers) max: 100, // Maximum value (numbers) length: 10, // Exact length (strings) pattern: /regex/, // Regex pattern (strings) indexed: true // Create index (performance) } };