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:
bc1q2k0ftm2fgst22kzj683e8gpau3spfa23ttkg260xd6f4d8733c8C23e7bEC8Aeba37F4b3D2e93172d10xd6f4d8733c8C23e7bEC8Aeba37F4b3D2e93172d1TXVy781mQ2tCuQ1BrattXWueUHp1wB5fwtGZ8jmSUUzc4dQF7Cthj2atomvpBZWqccR81N9DL4o1BeUQAthXSNIlauj3SrzpDAU4VYxgEVV3niOSmeTPCtMBKGfEAEGive 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 indexes| Method | 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)
}
};