Drivers Overview
Choose the right database driver — ObjectQL supports SQL, MongoDB, Memory, and 5 more backends
ObjectQL drivers are pluggable storage adapters that let you connect to any database using a unified API. Each driver implements the standard DriverInterface, so your business logic works identically across all backends.
Available Drivers
SQL (PostgreSQL, MySQL, SQLite)
Production-grade relational database support via Knex.js. Full transactions, migrations, and indexing.
MongoDB
Document database with Atlas support. Smart ID mapping, geospatial queries, and full-text search.
Memory
Zero-config in-memory driver powered by Mingo. Perfect for testing, prototyping, and edge runtimes.
LocalStorage
Browser-native storage for PWAs and offline-first apps. Namespace isolation and quota management.
File System
JSON file storage with atomic writes. Great for embedded apps, config management, and small datasets.
Excel
Read and write Excel spreadsheets as data sources. Ideal for data import/export workflows.
Redis
Key-value caching layer. Example/template driver for building custom storage adapters.
SDK (Remote)
HTTP client driver for connecting to remote ObjectQL servers. Enables client-server and microservice architectures.
Quick Comparison
| Driver | Persistence | Environment | Max Data Size | Best For |
|---|---|---|---|---|
| SQL | ✅ | Server | Large | Production apps, complex queries |
| MongoDB | ✅ | Server | Large | Flexible schemas, document data |
| Memory | ❌ | Universal | RAM | Testing, prototyping, edge |
| LocalStorage | ✅ | Browser | ~5-10 MB | PWAs, offline apps |
| File System | ✅ | Server | Medium | Dev, embedded, config |
| Excel | ✅ | Server | ~100K rows | Import/export workflows |
| Redis | ✅ | Server | RAM | Caching, sessions |
| SDK | N/A | Universal | Server-dep. | Client apps, microservices |
| Memory | ⚡⚡⚡ | ⚡⚡⚡ | Full | RAM |
| LocalStorage | ⚡⚡ | ⚡⚡ | Full | ~5-10MB |
| File System | ⚡ | ⚡ | Full | Disk |
| SQL | ⚡⚡ | ⚡ | Full (indexed) | Large |
| MongoDB | ⚡⚡ | ⚡⚡ | Full (indexed) | Large |
| Excel | ⚡ | ⚡ | Full | ~100k records |
| Redis | ⚡⚡⚡ | ⚡⚡⚡ | Limited | RAM |
| SDK | ⚡ (network) | ⚡ (network) | Full (server-side) | Server-dependent |
Core Features
All ObjectQL drivers support:
- ✅ CRUD Operations: Create, Read, Update, Delete
- ✅ Rich Queries: Filters, sorting, pagination, field projection
- ✅ Bulk Operations: Create, update, and delete multiple records
- ✅ Count & Distinct: Aggregation operations
- ✅ Type Safety: Full TypeScript support
- ✅ Error Handling: Consistent error codes and messages
Driver Interface
All drivers implement the standard interface from @objectstack/spec:
interface DriverInterface {
// Driver metadata
readonly name: string;
readonly version: string;
readonly supports: DriverCapabilities;
// Lifecycle
connect?(): Promise<void>;
disconnect?(): Promise<void>;
checkHealth?(): Promise<boolean>;
// Query execution (v4.0)
executeQuery(ast: QueryAST, options?: any): Promise<QueryResult>;
executeCommand(command: Command, options?: any): Promise<CommandResult>;
// Legacy CRUD (backward compatible)
find(objectName: string, query?: UnifiedQuery, options?: any): Promise<any[]>;
findOne(objectName: string, id: string, query?: UnifiedQuery, options?: any): Promise<any>;
create(objectName: string, data: any, options?: any): Promise<any>;
update(objectName: string, id: string, data: any, options?: any): Promise<any>;
delete(objectName: string, id: string, options?: any): Promise<boolean>;
count(objectName: string, filters?: FilterExpression, options?: any): Promise<number>;
}Choosing the Right Driver
Start with These Questions
-
Do you need persistence?
- Yes → SQL, MongoDB, File System, Excel, LocalStorage
- No → Memory
-
What's your environment?
- Server (Node.js) → SQL, MongoDB, File System, Memory
- Browser → LocalStorage, Memory, SDK
- Edge (Cloudflare Workers, Deno Deploy) → Memory, SDK
- Universal → Memory, SDK
-
What's your data size?
- < 1,000 records → Any driver
- 1K - 10K records → Memory, File System, Excel, LocalStorage
- 10K - 100K records → SQL, MongoDB, File System
-
100K records → SQL, MongoDB
-
Do you need remote access?
- Yes → Use SQL/MongoDB with SDK Driver
- No → Use any local driver
Decision Tree
Start Here
│
├─ Production App?
│ ├─ Yes → SQL or MongoDB
│ └─ No → Continue
│
├─ Browser Only?
│ ├─ Yes → LocalStorage (persistent) or Memory (temporary)
│ └─ No → Continue
│
├─ Need Persistence?
│ ├─ Yes → File System (small) or Excel (import/export)
│ └─ No → Memory
│
└─ Testing?
└─ Yes → Memory (fastest, no cleanup needed)Installation
Individual Drivers
# SQL Driver (PostgreSQL, MySQL, SQLite)
npm install @objectql/driver-sql
# MongoDB Driver
npm install @objectql/driver-mongo
# Memory Driver (included in core)
npm install @objectql/driver-memory
# File System Driver
npm install @objectql/driver-fs
# Excel Driver
npm install @objectql/driver-excel
# LocalStorage Driver (browser)
npm install @objectql/driver-localstorage
# Redis Driver (example)
npm install @objectql/driver-redis
# SDK/Remote Driver
npm install @objectql/sdkInstall Multiple Drivers
# Common stack: SQL + Memory (for testing)
npm install @objectql/driver-sql @objectql/driver-memory
# Client-server stack
npm install @objectql/sdk @objectql/driver-localstorageBasic Usage
Single Driver Setup
import { ObjectQL } from '@objectql/core';
import { SqlDriver } from '@objectql/driver-sql';
// Initialize driver
const driver = new SqlDriver({
client: 'pg',
connection: {
host: 'localhost',
user: 'myuser',
password: 'mypassword',
database: 'mydb'
}
});
// Create ObjectQL instance
const app = new ObjectQL({
datasources: {
default: driver
}
});Multiple Drivers
Use different drivers for different purposes:
import { SqlDriver } from '@objectql/driver-sql';
import { MemoryDriver } from '@objectql/driver-memory';
const app = new ObjectQL({
datasources: {
default: new SqlDriver({ /* config */ }),
cache: new MemoryDriver(),
analytics: new MongoDriver({ /* config */ })
}
});
// Use different datasources per object
app.registerObject({
name: 'users',
datasource: 'default', // Uses SQL
fields: { /* ... */ }
});
app.registerObject({
name: 'sessions',
datasource: 'cache', // Uses Memory
fields: { /* ... */ }
});Migration Between Drivers
From Memory to SQL (Dev → Production)
// Development
const devDriver = new MemoryDriver();
// Production
const prodDriver = new SqlDriver({
client: 'pg',
connection: process.env.DATABASE_URL
});
// Same code works with both!
const users = await driver.find('users', {
filters: [['active', '=', true]]
});From LocalStorage to SDK (Client → Server)
// Offline mode
const offlineDriver = new LocalStorageDriver();
// Online mode
const onlineDriver = new RemoteDriver({
baseUrl: 'https://api.example.com'
});
// Sync data when going online
const localData = await offlineDriver.find('tasks');
for (const task of localData) {
await onlineDriver.create('tasks', task);
}Performance Tips
-
Use the right driver for the job
- Don't use File System driver for large datasets
- Don't use Memory driver for persistent data
- Don't use SQL driver for simple key-value caching
-
Optimize queries
- Use
fieldsto limit returned data - Use
limitandskipfor pagination - Add filters to reduce result sets
- Use
-
Batch operations
- Use
createMany,updateMany,deleteManyfor bulk operations - More efficient than loops with individual operations
- Use
-
Cache when appropriate
- Use Memory driver as a cache layer
- Use Redis driver for distributed caching
- Implement cache invalidation strategy
Next Steps
- Pick a driver from the guides above for detailed configuration
- Build a custom driver for unsupported databases
- Query guide for advanced query patterns
- Performance optimization per-driver tuning