Databases are essential for persisting data in Node.js applications. Depending on the application, you can fall back on the most diverse implementations. A slim alternative to heavyweight databases is Node.js lowdb.

Common to all databases is that you must install the database software and run a server process. In some scenarios, however, this means an unnecessarily large overhead. Especially if you just want to test something fast or if you are in an environment where you can not install any additional software.

A lightweight alternative is SQLite, a file-based SQL database. But you also have to compile the database driver here. To avoid that, the database exists called lowdb. This database is based on the library Lodash. The data is recorded in a JSON file. Since the database stores the data in plain text, it in no way approaches the performance of a full-fledged database, which usually stores the information in an optimized binary format. For this reason, the use of lowdb in productive operation is not recommended.

Node.js lowdb – Installation and first steps

Node.js lowdb can be installed via NPM and Yarn. For NPM, for example, the command is npm install lowdb . An adapter layer is used to access the data. Node.js lowdb supplies a number of adapters. The most important are FileSync and FileAsync for synchronous or asynchronous access.

Before you can work with the database, you must first initialize the adapter. In doing so, you pass the constructor the name of the file in which the information is to be saved. The file may already exist and be prefilled with information. If the file does not exist, it is created by lowdb. You then pass the object representation of the adapter to lowdb. If the database file does not yet exist, you must predefine the structure of the database. To do this, call the defaults method and pass the names of each object store . Then call the write method to persist the information. Example 1 summarizes these steps for you:

//const low = require('lowdb'); //const FileSync = require('lowdb/adapters/FileSync'); //const adapter = new FileSync('db.json'); //const db = low(adapter); //db.defaults({ users: [] }).write();

Lets how to use lowdb to perform all CRUD operations.

Node.js lowdb – CRUD operations

Create records

If you do not already start with a filled database, the first step is to create new records that you can read at a later date. lowdb provides the push method for this purpose. Access to an object store is always done in the same way: First, get a reference to the object store you want, then execute the actual operation, and then call the write method to persist the operation. A concrete example of such an operation can be found in example 2.

// const user = { // id: 1, // firstname: 'John', // lastname: 'Doe', // year: 1965 // } // db.get('users').push(user).write();

When executing the code in example 1 and 2, the db.json file is created containing a JSON object with the users key and an array containing the user object from example 2.

Read records

Now that you have a first record, you can switch to reading it from the database again. Since you are currently using the FileSync adapter, you do not have to worry about callbacks or promises, but get the value directly from the database. In the simplest case, call the value store on the object store. This will get all records as an array. If you are only interested in certain datasets, you can use the filter method. The sort method is used for sorting. Example 3 ensures that only user objects with the first name John are inserted in the variable John.

// const John = db.get('users') // .filter({firstname: 'John'}) // .value(); // console.log(John);

Update records

The records in the database can also be easily updated with lowdb. To do this, the record must first be localized with the find method. You can then change the value using the assign method. To make the change effective, the write method must be called. Example 4 changes the firstname property of the record.

// db.get('users') // .find({firstname: 'John'}) // .assign({firstname: 'William'}) // .write();

When calling the assign method, the specified fields are overwritten with the corresponding values. All fields that are not specified remain unchanged.

Delete records

Similar to the find method for localizing records, the remove method can also be used to delete records. You just have to pass the criteria in the form of an object. Again, calling the write method is required to persist the change. Example 5 deletes the record with the first name William.

// db.get('users') // .remove({firstname: 'William'}) // .write();

You can check whether the delete operation worked either with a read query or by looking in the db.json file.

Asynchronous access

The examples so far have used the FileSync adapter. However, most databases work asynchronously so as not to block the execution of the application. Also, lowdb has an asynchronous adapter. Instead of the FileSync adapter, you must instantiate the FileAsync adapter and pass it to lowdb. Then you can use the interfaces of lowdb as usual. The only difference is that both the write and the value methods return Promises instead of concrete values. In order to keep the source code clear, the use of async / await is recommended . Example 6 shows an example in which a record is first created and then read out of the database again.

// const adapter = new FileAsync('db.json'); // (async function () { // const db = await low(adapter); // db.defaults({ users: [] }).write(); // const user = { // id: 1, // firstname: 'John', // lastname: 'Doe', // year: 1965 // } // await db.get('users').push(user).write(); // const john = await db.get('users') // .filter({firstname: 'John'}) // .value(); // console.log(john); // })();

Conclusion

Node.js lowdb is a lightweight and flexible database that is ideal for small experiments. In any environment where a large database is too much overhead or a database driver can not be installed, lowdb can be used as an alternative. For example, the npm json-server package relies on lowdb.