The First Object Database for Node: Introducing Realm Node.js

At Realm, we’re very focused on mobile developers, and have built and open-sourced Realm Mobile Database versions for Swift, Objective-C, Java, Xamarin, and React Native. But today, we’re announcing something completely different: Realm Node.js. We’re pretty sure this is the first real object database for Node, and is available today on NPM as a free and fully open source repo – just run npm install --save realm.

Over the years, we’ve had tons of requests from mobile developers for a version of Realm that worked on the server, so it’s long been on our backlog, though not highly prioritized. But our priorities changed when we released the new Realm Mobile Platform in September, and potential customers started asking us for a Node interface for the platform. We pretty quickly made Node part of the platform product strategy (more on that in a few days), and that led to the creation of Realm Node.js.

What is it, and what is it for?

Realm is an object database. It means that you simply work with objects, as you’re used to, except that these objects persist to disk easily and performantly in a Realm. You don’t have to serialize them into JSON, and you don’t have to send them through an ORM to store them in tables. You stick with the principles that object-oriented development encourages, and you make the thing you set out to make. It works on all the mobile client side platforms – and now Node.js on the server side as well.

For mobile developers, Realm Node.js means you can create and send pre-populated Realms to clients, which is very handy for a number of reasons, including getting around pesky app size limits. That’s the primary reason mobile dev have asked us for something like this over the years.

But things got even more interesting when we showed some early versions to backend developers and learned that it might be a lot more broadly useful to the Node community than we originally imagined. For example, we realized that it is useful for sharing live data between multiple Node instances. To illustrate this, we threw together a quick demo to show you how you can use Realm to get two Node processes on the same machine to work together, without the burden of serializing and deserializing the objects with which both need to work.

One of the unique features of Realm is its reactive architecture. Underneath the hood, Realm uses Multiversion Concurrency Control to provide concurrent access to the database across threads and processes. This means that readers are never blocked against a writer and each has a consistent view of the database–ensuring Realm’s ACID compliance. To coordinate this, Realm uses a notification system to update accessors when a write transaction completes. Developers can take advantage of this through Realm’s notification APIs to react to changes. This example demonstrates how a Node.js developer can use this functionality to coordinate two independent services by using Realm for interprocess communication.

In the example, we use two popular Node.js libraries: Express, a web framework, and Winston, a logging library. We will use Express to create HTTP endpoints and Winston to log information about the requests:

var express = require('express'),
    util = require('util'),
    winston = require('winston');
    RealmWinston = require('./winston-realm').Realm;

var app = express();

// Use custom Winston transport: RealmWinston
// Writes log data to winston.realm
winston.add(RealmWinston, {});

app.get('/', function (req, res) {
  res.send('Hello World!');
  winston.info('Handled Hello World');
});

app.use(function (req, res, next) {
  res.status(404).send('Sorry can not find that!');
  winston.error('404 Error at: ' + req.url);
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

To take advantage of Realm, we created a custom transport for Winston that saves the log data to a Realm file. At the base path, we log an info message confirming the “Hello World” response. For all other paths, we respond with a 404 error and log the corresponding path in a error message. By saving the log data in Realm, we can then start another Node process and register a Realm listener to react to changes:

'use strict';

var Realm = require('realm');

let winstonRealm = new Realm({
  path: 'winston.realm'
});

// Register listener to print out log messages at error level
winstonRealm.objects('Log').filtered('level = "error"').addListener((logs, changes) => {
  changes.insertions.forEach((index) => {
    let log = logs[index];
    console.log(log.message);
  })
});

The listener uses Realm’s support for collection notifications, which passes the specific changes as indexes corresponding to the inserted, deleted, or modified objects. The example adds a listener to a query of all logs at the error level and then prints the log message to the console.

While this example is simple, this setup could be used in more advanced scenarios to coordinate data across microservice architectures. Check out the complete demo here. When you’re ready to use Realm in your own Node.js projects, you can find the answers you need in our React Native documentation and our API docs (since the codebase is shared between all our JavaScript platforms).

What else can you use Realm Node.js for? Work with datasets bigger than local memory. Use as queryable and observable data structures. Build reactive architectures across multiple Node instances. Or perhaps for communication between Docker images? We’re eager to hear what you do with it!

Ready for Realtime and Scale: Announcing Realm Mobile Platform 1.0

We’re proud to announce Realm Mobile Platform has left beta status and graduated to version 1.0! We’ve been hard at work fixing bugs, polishing rough edges, hardening the code, and adding more than a few new features. Learn more in the announcement post!


Realm Team

Realm Team

At Realm, our mission is to help developers build better apps faster. We provide a unique set of tools and platform technologies designed to make it easy for developers to build apps with sophisticated, powerful features — things like realtime collaboration, augmented reality, live data synchronization, offline experiences, messaging, and more.

Everything we build is developed with an eye toward enabling developers for what we believe the mobile internet evolves into — an open network of billions of users and trillions of devices, and realtime interactivity across them all.