{"id":16441,"library":"minimongo","title":"Minimongo","description":"Minimongo is a client-side, in-memory MongoDB clone designed for browser and Node.js environments, offering a MongoDB-like API for CRUD operations and query syntax. It supports various local storage backends including IndexedDB, WebSQL (legacy), LocalStorage, and a purely in-memory option, with an autoselection utility. Currently at version 7.1.1, the project aims for stable releases without a strict public cadence, evolving from a 2014 fork of Meteor.js's minimongo package to incorporate more geospatial queries and npm-friendliness. Its key differentiators include hybrid local/remote synchronization with conflict resolution using base documents, replication between database instances, and support for Extended JSON (EJSON). While it offers a substantial subset of MongoDB query features, it does not support the full aggregation pipeline or all operators.","status":"active","version":"7.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/mWater/minimongo","tags":["javascript","mongodb","mongo","minimongo","IndexedDb","WebSQL","storage","typescript"],"install":[{"cmd":"npm install minimongo","lang":"bash","label":"npm"},{"cmd":"yarn add minimongo","lang":"bash","label":"yarn"},{"cmd":"pnpm add minimongo","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Optional plugin for SQLite storage backend in hybrid mobile environments.","package":"cordova-sqlite-storage","optional":true}],"imports":[{"note":"Minimongo primarily uses ESM imports for modern JavaScript environments. CommonJS `require` might work in some bundler setups but is not the recommended or officially documented approach.","wrong":"const MemoryDb = require('minimongo').MemoryDb;","symbol":"MemoryDb","correct":"import { MemoryDb } from 'minimongo';"},{"note":"A named import for the IndexedDB storage backend. Note that the constructor is callback-based.","wrong":"const IndexedDb = require('minimongo').IndexedDb;","symbol":"IndexedDb","correct":"import { IndexedDb } from 'minimongo';"},{"note":"HybridDb is a named export. Ensure to use destructuring for import.","wrong":"import HybridDb from 'minimongo'; // Incorrect default import","symbol":"HybridDb","correct":"import { HybridDb } from 'minimongo';"},{"note":"The `utils` object containing helper functions like `autoselectLocalDb` is a named export.","wrong":"import * as utils from 'minimongo'; // Not explicitly documented, might import more than needed\nconst utils = require('minimongo').utils;","symbol":"utils","correct":"import { utils } from 'minimongo';"}],"quickstart":{"code":"import { IndexedDb, HybridDb, RemoteDb, MemoryDb } from 'minimongo';\n\ninterface MyDocument {\n  _id?: string;\n  name: string;\n  age: number;\n  tags?: string[];\n}\n\nasync function setupDatabase() {\n  return new Promise<IndexedDb<MyDocument>>((resolve, reject) => {\n    const indexedDb = new IndexedDb<MyDocument>(\n      { namespace: 'myAppDb', autoCreate: true },\n      () => {\n        console.log('IndexedDb initialized successfully.');\n        resolve(indexedDb);\n      },\n      (error: Error) => {\n        console.error('IndexedDb initialization failed:', error);\n        reject(error);\n      }\n    );\n  });\n}\n\nasync function runApp() {\n  try {\n    const localDb = await setupDatabase();\n    const remoteDb = new RemoteDb('/api/collections', 'myAppDb', {\n      // For a real application, replace with a proper HTTP client\n      // This is a minimal mock for demonstration\n      httpClient: {\n        get: async (url: string) => {\n          console.log(`[RemoteDb] GET ${url}`);\n          if (url.includes('myAppDb/items')) {\n            return { status: 200, data: [{ _id: 'remote1', name: 'Remote Item', age: 30 }] };\n          }\n          return { status: 404, data: { message: 'Not Found' } };\n        },\n        put: async (url: string, data: any) => {\n          console.log(`[RemoteDb] PUT ${url}`, data);\n          return { status: 200, data: { ...data, _id: data._id || 'newRemoteId' } };\n        }\n      },\n      useQuickFind: true\n    });\n\n    const hybridDb = new HybridDb(localDb, remoteDb);\n    hybridDb.addCollection('items');\n    const itemsCollection = hybridDb.getCollection('items');\n\n    // Insert a document locally\n    const newItem: MyDocument = { name: 'Local Item', age: 25, tags: ['frontend'] };\n    await itemsCollection.upsert(newItem, null, (doc: MyDocument) => {\n      console.log('Inserted local item:', doc);\n    });\n\n    // Query local and remote (hybrid sync)\n    console.log('\\nQuerying all items (local and remote sync):');\n    itemsCollection.find({}).fetch((docs: MyDocument[]) => {\n      console.log('Found items:', docs);\n    });\n\n    // Demonstrate another local operation\n    const anotherItem: MyDocument = { name: 'Another Item', age: 40 };\n    await itemsCollection.upsert(anotherItem, null, (doc: MyDocument) => {\n      console.log('Inserted another local item:', doc);\n    });\n\n    // Query with selector\n    console.log('\\nQuerying items with age > 25:');\n    itemsCollection.find({ age: { $gt: 25 } }).fetch((docs: MyDocument[]) => {\n      console.log('Found items (age > 25):', docs);\n    });\n\n  } catch (error) {\n    console.error('Application failed:', error);\n  }\n}\n\nrunApp();\n","lang":"typescript","description":"This quickstart demonstrates initializing an IndexedDb locally, setting up a mock RemoteDb, creating a HybridDb for combined local/remote operations, and performing basic CRUD and queries with synchronization."},"warnings":[{"fix":"Thoroughly test query selectors against Minimongo's capabilities. For unsupported operations, consider performing data manipulation client-side after fetching or implementing server-side logic.","message":"Minimongo's MongoDB query language support is partial, lacking full aggregation pipeline, `findAndModify`, `map/reduce`, and some specific modifiers like `$pull` with certain selectors. Developers should consult the documentation for supported operators to avoid unexpected query behavior.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Prefer using the IndexedDb backend for persistent storage in modern browsers. MemoryDb or LocalStorageDb can be used for simpler, less data-intensive persistence needs.","message":"WebSQL is a deprecated browser technology. While Minimongo offers a WebSQLDb backend, its use is discouraged for new applications and may lead to compatibility issues or removal in future browser versions.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Wrap callback-based APIs in Promises for easier integration with `async/await` patterns or explicitly use callbacks as demonstrated in the documentation.","message":"The `IndexedDb` constructor (and potentially other async operations) uses Node.js-style callbacks (`success`, `error`) rather than modern Promises or async/await. This can be a source of confusion for developers accustomed to Promise-based asynchronous patterns.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Understand and correctly implement the base document concept for `upsert` operations, especially in multi-user or multi-client environments, to ensure proper conflict resolution. Review the documentation on hybrid sync and conflict handling.","message":"When using `HybridDb` for synchronization, conflict resolution relies on 'base documents' provided during `upsert` operations. Incorrectly supplying or omitting base documents can lead to unintended data overwrites or sync issues.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Refer exclusively to the `mWater/minimongo` documentation for this specific package. Avoid assuming direct API parity with Meteor's integrated Minimongo.","message":"Minimongo, having forked from Meteor.js's minimongo in 2014, may have API differences or behavioral nuances compared to the current official Meteor `minimongo` package. Developers familiar with Meteor's ecosystem should be aware that this standalone package is independently maintained.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure you call `.fetch()` on the result of `find()` and provide a callback, e.g., `collection.find(selector).fetch((docs) => { /* handle docs */ });`.","cause":"The `find` method returns a cursor-like object. To retrieve documents, you must call `.fetch()` on the cursor, usually with a callback.","error":"TypeError: collection.find(...).fetch is not a function"},{"fix":"Ensure that `IndexedDb` is initialized only once per namespace, or handle database closing and reopening carefully. Check for pending transactions or other open connections.","cause":"Attempting to initialize IndexedDb multiple times or with conflicting options without properly closing previous connections, or a previous operation is still pending.","error":"Uncaught DOMException: Failed to execute 'open' on 'IDBFactory': The database connection is already open, or there is a pending upgrade transaction."},{"fix":"Refactor your query to use only the supported logical, comparison, element, and array operators listed in Minimongo's documentation. Complex logic may need to be implemented in client-side code after fetching data.","cause":"Minimongo only implements a subset of MongoDB's query operators and aggregation features. The operator used is not supported by this library.","error":"Error: Unsupported query operator: $someUnsupportedOperator"},{"fix":"Use ES module `import` syntax (e.g., `import { NamedExport } from 'minimongo';`) instead of `require()`. Ensure your project's `package.json` specifies `\"type\": \"module\"` or that files use `.mjs` extension for ESM.","cause":"This error occurs in modern browser environments or Node.js projects configured for ESM, when attempting to use CommonJS `require()` syntax. Minimongo is primarily designed for ESM imports.","error":"ReferenceError: require is not defined"}],"ecosystem":"npm"}