MarsDB Client-Side Database
raw JSON →MarsDB is a lightweight client-side database inspired by Meteor's minimongo implementation, providing a MongoDB-like API for JavaScript environments. It offers a Promise-based interface, observable cursors, and reactive joins, making it well-suited for applications requiring real-time data reactivity. Written in ES6, it operates across various JavaScript platforms including browsers, Electron, NW.js, and Node.js. The current stable version is 0.6.11. The project appears to be in a maintenance phase, with recent activity primarily focused on bug fixes rather than significant new feature development. Its key differentiators include a flexible pluggable storage architecture (supporting in-memory, LocalStorage, LevelUP, and even MongoDB wrappers), a powerful pipeline for data transformation, and compatibility with a wide range of MongoDB query and modifier operations.
Common errors
error ReferenceError: Promise is not defined ↓
import 'marsdb/polyfills'; or require('marsdb/polyfills'); at the top of your main application file to ensure Promises are available. error TypeError: users.count is not a function ↓
.fetch() to the count() call to retrieve the actual number: await users.find({}).count().fetch(). error Error: Cursor is executing, cannot modify ↓
whenNotExecuting() method to safely queue changes: await cursor.whenNotExecuting(); cursor.sort({ name: 1 }); error TypeError: Cannot read property 'setStorageManager' of undefined ↓
npm install marsdb-localforage) and import it separately, then apply it to your collection: import LocalForageManager from 'marsdb-localforage'; const users = new Collection('users', { StorageManager: LocalForageManager }); Warnings
breaking The `static` and `method` methods were removed from the Collection class. The internal Document wrapping of objects was also removed for performance improvements. ↓
breaking The `count()` and `ids()` methods of a Cursor no longer return direct values (a number or an array of IDs) but now return observable cursors themselves. ↓
breaking Core storage implementations (e.g., LevelUP, LocalStorage) and the AngularJS binding were refactored into separate, dedicated npm packages (e.g., `marsdb-levelup`, `marsdb-angular`). They are no longer bundled with the main `marsdb` package. ↓
gotcha Modifying a Cursor object while it is actively executing (e.g., changing its query or sort parameters) will throw an error. This is to prevent inconsistent states. ↓
gotcha For JavaScript environments that lack native ES6 features like `Promise`, `Set`, and `Symbol`, the `marsdb/polyfills` module must be explicitly imported to provide these globals. ↓
Install
npm install marsdb yarn add marsdb pnpm add marsdb Imports
- Collection wrong
import { Collection } from 'marsdb'; const Collection = require('marsdb').Collection;correctimport Collection from 'marsdb'; - Polyfills (side effect) wrong
import { polyfills } from 'marsdb'; const polyfills = require('marsdb').polyfills;correctimport 'marsdb/polyfills';
Quickstart
import Collection from 'marsdb';
async function runMarsDBExample() {
// Create a new collection named 'users'
const users = new Collection('users');
// Clear existing data for a clean run
await users.remove({});
// Insert documents
const insertResult = await users.insert([
{ _id: '1', name: 'Alice', age: 30, city: 'New York' },
{ _id: '2', name: 'Bob', age: 24, city: 'Los Angeles' },
{ _id: '3', name: 'Charlie', age: 30, city: 'Chicago' },
{ _id: '4', name: 'Diana', age: 28, city: 'New York' }
]);
console.log(`Inserted ${insertResult.length} users.`);
// Find users aged 30
const agedThirty = await users.find({ age: 30 }).fetch();
console.log('Users aged 30:', agedThirty);
// Find users in New York, sorted by name
const nyUsers = await users.find({ city: 'New York' })
.sort({ name: 1 })
.fetch();
console.log('Users in New York (sorted):', nyUsers);
// Update Alice's age
await users.update({ name: 'Alice' }, { $set: { age: 31 } });
const updatedAlice = await users.findOne({ name: 'Alice' });
console.log('Updated Alice:', updatedAlice);
// In a real application, observable cursors would react to changes.
// For a quickstart, we just fetch all current users.
const allUsers = await users.find({}).fetch();
console.log('All current users:', allUsers);
}
runMarsDBExample().catch(console.error);