Skip to content
An easy to use DDP client library
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
docs v 2.2.4 Aug 6, 2019
src v 2.2.4 Aug 6, 2019
test v 2.2.4 Aug 6, 2019
.babelrc 1.2.0. Dec 31, 2018
.gitignore init Apr 9, 2018
.npmignore pre 1.1.7 Oct 28, 2018
.travis.yml v1.1.0 Oct 15, 2018 v 2.2.4 Aug 6, 2019
LICENSE merge fix Jul 25, 2019 v 2.2.4 Aug 6, 2019 v 2.1.0 Jul 22, 2019
jsdoc_conf.json docs fix Jul 25, 2019 1.2.0. Dec 31, 2018
package-lock.json v 2.2.4 Aug 6, 2019
package.json v 2.2.4 Aug 6, 2019

npm version Build Status Dependency Status devDependency Status

SimpleDDP 🥚

The aim of this library is to simplify the process of working with Meteor.js server over DDP protocol using external JS environments (like Node.js, Cordova, Ionic, ReactNative, etc).

It is battle tested 🏰 in production and ready to use 🔨.

If you like this project ⭐ is always welcome.


SimpleDDP is written in ES6 and uses modern features like promises. Though its precompiled with Babel, your js environment must support ES6 features. So if you are planning to use SimpleDDP be sure that your js environment supports ES6 features or include polyfills yourself (like Babel Polyfill).

Project uses semantic versioning 2.0.0.

DDP (protocol) specification.



npm install simpleddp --save



Adding custom EJSON types


First of all you need WebSocket implementation for your node app. We will use isomorphic-ws package for this since it works on the client and serverside.

npm install isomorphic-ws ws --save

Import/require simpleDDP.

const simpleDDP = require("simpleddp"); // nodejs
const ws = require("isomorphic-ws");


import simpleDDP from 'simpleDDP'; // ES6
import ws from 'isomorphic-ws';

Now you should make a new simpleDDP instance.

let opts = {
    endpoint: "ws://",
    SocketConstructor: ws,
    reconnectInterval: 5000
const server = new simpleDDP(opts);

Connection is not going to be established immediately after you create a simpleDDP instance. If you need to check your connection simply use server.connected property which is true if you are connected to the server, otherwise it's false.

You can also add some events for connection status.

server.on('connected', () => {
    // do something

server.on('disconnected', () => {
    // for example show alert to user

server.on('error', (e) => {
    // global errors from server

As an alternative you can use a async/await style (or then(...)).

(async ()=>{
  await server.connect();
  // connection is ready here

The next thing we are going to do is subscribing to some publications.

let userSub = server.subscribe("user_pub");
let otherSub = server.subscribe("other_pub",'param1',2); // you can specify arguments for subscription

(async ()=>{
  await userSub.ready();
  let nextSub = server.subscribe("next_pub"); // subscribing after userSub is ready
  await nextSub.ready();
  //all subs are ready here

You can fetch all things you've subscribed for using server.collection method. Also you can get reactive data sources (plain js objects which will be automatically updated if something changes on the server).

(async ()=>{

  // call some method

  let userSub = server.subscribe("user",userId);
  await userSub.ready();

  // get non-reactive user object
  let user = server.collection('users').filter(user=>[0];

  // get reactive user object
  let userReactiveCursor = server.collection('users').filter(user=>;
  let userReactiveObject =;

  // observing the changes
    console.log('previus user data',state.prev);
    console.log('next user data',;

  // observing changes in reactive data source
    console.log('new user state', newData);

  let participantsSub = server.subscribe("participants");

  await participantsSub.ready();

  let reactiveCollection = server.collection('participants').reactive();

  // reactive reduce
  let reducedReactive = reactiveCollection.reduce((acc,val,i,arr)=>{
    if (i<arr.length-1)  {
      return acc + val.age;
    } else {
      return (acc + val.age)/arr.length;

  // reactive mean age of all participants
  let meanAge =;

  // observing changes in reactive data source
    console.log('new user state', newData);
You can’t perform that action at this time.