LokiJS In-Memory Database
LokiJS is a fast, document-oriented JavaScript in-memory database designed for various environments including browsers, Node.js, and NativeScript. It functions by storing JavaScript objects as documents in a NoSQL fashion, enabling high-performance retrieval through indexing and dynamic views. Currently at version 1.5.12, its release cadence appears infrequent, with the last major update several years ago. Key differentiators include its small footprint, suitability for client-side session stores, and built-in persistence adapters (like localStorage, IndexedDB, or filesystem) that can be extended with custom solutions. It prioritizes speed by maintaining unique and binary indexes and offering dynamic views for frequently accessed data subsets, making it ideal for performance-critical applications where data can reside primarily in memory.
Common errors
-
Trying to update unsynced document. Please save the document first by using insert() or addMany()
cause Attempting to update a document by passing a new object literal or a document missing the internal '$loki' ID.fixAlways retrieve the document from the collection, modify the returned object reference, and then pass that specific object to `collection.update()`. Example: `const doc = collection.findOne({ id: 1 }); doc.field = 'newValue'; collection.update(doc);` -
Error: Cannot find module 'lokijs'
cause Incorrect import path or CommonJS `require()` syntax in an environment where ESM is expected, or vice-versa, or bundling issues in environments like Electron.fixFor Node.js, ensure `const Loki = require('lokijs');` is used. For modern browsers or bundlers supporting ESM, use `import Loki from 'lokijs';`. If using a specific adapter, ensure the path `lokijs/src/loki-adapter-name` is correct. Verify `lokijs` is correctly installed in `node_modules` and your build process includes it.
Warnings
- breaking Some external sources (e.g., database.guide) claim LokiJS was abandoned in 2022 and its official website redirects to RxDB, suggesting a lack of active development or future deprecation in favor of alternatives. While the GitHub repository shows some recent minor commits, the discrepancy and the outdated README (referencing v1.3 while npm is v1.5.12) indicate potential long-term maintenance uncertainty and recommend evaluating alternatives like RxDB for new projects.
- gotcha LokiJS is an in-memory database, meaning data is lost upon application restart or browser refresh unless a persistence adapter is explicitly configured. Default behavior is purely in-memory.
- gotcha Using plain LokiJS across multiple browser tabs can lead to data loss due to instances overwriting each other's persistence. LokiJS loads data in bulk and periodically persists it, which is not designed for concurrent multi-tab writes without external coordination.
- gotcha When updating documents, you must pass an existing document object (which contains the `$loki` ID) to the `collection.update()` method. Passing a plain object or a modified copy without the `$loki` property will result in a 'Trying to update unsynced document' error.
Install
-
npm install lokijs -
yarn add lokijs -
pnpm add lokijs
Imports
- Loki
import { Loki } from 'lokijs';import Loki from 'lokijs';
- Loki
const { Loki } = require('lokijs');const Loki = require('lokijs'); - LokiLocalStorageAdapter
import { LokiLocalStorageAdapter } from 'lokijs';import LokiLocalStorageAdapter from 'lokijs/src/loki-local-storage-adapter';
Quickstart
import Loki from 'lokijs';
import LokiLocalStorageAdapter from 'lokijs/src/loki-local-storage-adapter';
const dbName = 'myCoolDatabase.db';
const adapter = new LokiLocalStorageAdapter(dbName);
const db = new Loki(dbName, {
adapter: adapter,
autoload: true,
autoloadCallback: databaseInitialize,
autosave: true,
autosaveInterval: 4000
});
function databaseInitialize() {
let users = db.getCollection('users');
if (users === null) {
users = db.addCollection('users', { unique: ['email'] });
}
// Check if there's any data, if not, insert some
if (users.count() === 0) {
users.insert({ name: 'Alice', email: 'alice@example.com', age: 30 });
users.insert({ name: 'Bob', email: 'bob@example.com', age: 24 });
console.log('Initial data inserted.');
} else {
console.log('Database already contains data.');
}
const allUsers = users.find();
console.log('All users:', allUsers);
const youngUsers = users.find({ age: { '$lt': 25 } });
console.log('Users younger than 25:', youngUsers);
// Update an existing user
const alice = users.findOne({ name: 'Alice' });
if (alice) {
alice.age = 31;
users.update(alice);
console.log('Alice updated:', users.findOne({ name: 'Alice' }));
}
// Ensure data is saved after modifications if autosave is off or before manual exit
// db.saveDatabase(); // Autosave handles this in this example
}
console.log('LokiJS database initialized or loaded.');