We have received a number of requests for a comparison. I’d like to thank Nick Retallack
, who already did a great job summarizing a lot of these points on our Google Group
. Many of his observations are included here. A bit of the origin story
First of all, I should mention that Brian and I first met the Meteorteam last November when we demoed an early version of Derby at the Keeping it Realtime Conference
hosted by &yet
. When we met, the Meteor
team had already started on their framework, and the similarities wereobvious. Some time before, I had also met with David Greenspan (whorecently joined Meteor) to pick his brain and learn more about hisexperience writing Etherpad
. Our two teams like each other, we’ve been keeping in touch, and we have all learned a lot from each other.
Our teams share a similar vision for a world where all applicationsare realtime and collaborative by default. We as well as a number ofother other developers all had a revelation about a year and a halfago—the way that web apps are currently built makes it painfullydifficult to create the best user experience, where data dynamicallyupdate everywhere.
Brian and I first discussed this vision with each other a year ago. Iwas coming from working as a Product Manager on the Google Search team,and he had been working on a number of open source Node.js projectsincluding Mongoose
.I was interested in writing a framework, because I believed it was thebest way to write an app with the kind of performance that I desired,and Brian felt that the Node.js community needed an easy to useframework for those developers who preferred tools like Rails and PHP. The Holy Grail: server and client code sharing
Gmail, Twitter, and other sites rendered only in the client werepainfully slow to load. Twitter went through the full circle onthis—they started as a server-rendered Rails app, rewrote to render everything in the client
So after all that, our teams decided to go in similar directions insome ways, but very different in others. Derby’s goal is to make itpossible for any developer to write apps that load as fast as a searchengine, are as interactive as a document editor, and work offline. Andto quote Geoff
,Meteor’s goal is to create “a ‘mass-market’ app platform that could beused for 90% of the sites on the web, and for that 90%, make webdevelopment faster and within reach of more people.” GPL vs. MIT
Currently, Meteor is only available under a GPL license
.This means that you must contact them and arrange for a commerciallicense if you do not wish to release your source under the GPL oranother compatible license.
Derby, Racer, and all other components of our framework are releasedunder the permissive MIT license. Thus, you can do pretty much anythingyou want with it (other than sue us), and we can’t stop you or changeour minds later.
I’m no lawyer, so don’t take any of what I just said as legal advice;I don’t have a crystal ball or anything. (Yes, a lawyer once told me tosay that.) Meteor packages vs. npm
Meteor has created their own package system and means for distributing packages.
Node.js modules are clearly defined by the CommonJS format and thebuilt-in module APIs. However, it does not include a means fordistributing modules. In the early days, Node.js had a few competingpackage managers, but pretty much everyone has now finalized on using npm
. It is so universal, that npm is now distributed directly with the official Node.js binary distributions.
Frankly, this is the main thing that concerns me about Meteor. It islikely that many people trying Meteor will never have used Node.jsbefore, and they won’t appreciate the great benefits of distribution vianpm. I and many other developers view npm as one of Node.js’s corestrengths, and I would be very sad to see it weakened by an incompatiblepackage system.
Like pretty much every other Node.js project out there, we primarilydistribute Derby, Racer, and all plugins for these projects as npmmodules. We will continue to break out our projects into smaller modulesso that they can be better reused by others. Perhaps you don’t useDerby, but you need to parse some HTML. We had to write a simple andfast HTML parser for our templates to work, so you’ll be able to usejust that in any Node.js project. Connect
is great example of a project that has a rich ecosystem of middlewaredesigned to work with it that are all distributed via npm, and we hopeto follow in the same pattern. Compatibility with other libraries
Meteor makes it possible to replace parts of it with other libraries.It is especially flexible when it comes to substituting in client-sidelibraries, though those libraries must first be wrapped as a Meteorpackage.
Meteor mostly manages the creation of a server in a custom way. Thismakes it easy to create and deploy a Meteor app to their hostingservice, but it makes it much harder to use Meteor as a module of a moretraditional Node.js server.
In contrast, Derby is just a normal npm module that you can add to any Node.js server. If you want to use any of the 8900 packages
in npm (at the moment), simply add them to your package.json file and npm install away!
Derby does not provide any sort of hosting solution, though there arelots of great hosting services for Node.js out there. We will providebetter instructions for how to get Derby apps up and running quickly on apublic server in the future.Racer
(therealtime engine powering Derby’s models) is a separate module, and itcan be used independently of Derby. You could hook pretty much any UIlayer up to Racer and handle the methods that it emits as the model isupdated. Racer is built on top of the very popular Socket.IO
module, which you can use directly if you need to.
Derby also uses popular modules at its core, especially Express
for routing and Browserify
, which can bundle up most Node.js modules for the browser automatically. MongoDB API vs. Racer methods
Racer has its own API based around a set of mutator methods andpaths. This API maps pretty much 1:1 with any document store, includingMongoDB. This has some pluses and minuses, but we believe it is theright choice for a few reasons: Conflict resolution
Paths and methods map well to conflict detection techniques that wethink will be one of the major benefits of using Racer. For now, ourdefault mode is last-writer-wins, which is equivalent to how Meteorsaves data. However, we have preliminary implementations of conflictresolution via Software Transactional Memory and OperationalTransformation methods. Such techniques will make it possible to use aDerby app offline and then resync correctly. It will also make itpossible to easily add features like Google-Docs-style realtimecollaborative text editing in any text box. Datastore portability
Our paths and methods are granular enough to take advantage of thecapabilities of most datastores, but it is possible to switch from onedatastore to another or to use them with multiple datastoressimultaneously. Swapping in Riak, Postgres, CouchDB, or another serviceshould be straightforward without modifying application code. Efficient PubSub
Paths map well to PubSub, which is how we propagate changes inrealtime. In contrast, Meteor’s LiveMongo implementation simply writesto the database and polls it frequently for the data in use by everyconnected client. The advantage to polling is that it can supportsubscriptions to pretty much any kind of Mongo query, but we haveimplemented most queries and query PubSub without needing to poll thedatabase. We have no real-world evidence yet, but we expect PubSub toscale much better than database polling. API plugins
It will be possible to create plugins that act like datastores, eventhough they are communicating with a backend service or a 3rd party API.Database adapters are built on top of a system of routes that can beused in a custom manner. Server rendering and shared routes
Derby is one of the only frameworks designed to run all rendering androuting code on the server and in the browser. It’s even possible touse Derby to render static pages that share templates with dynamic apps.
This means you get crazy fast page loads with no effort. Even for asimple client-rendered app, pages typically take a second or two to loadand then be displayed to the user. Simple Derby apps can fire theonload event in less than 200ms. As apps get more complex, serverrendering has an even more drastic effect.
Lots of big companies including Google, Amazon, and Facebook dedicatemassive resources to optimizing page load time, because it directlytranslates into better conversion rates and more revenue. I died alittle bit inside the day Gmail added a loading progress bar. Don’t dothat.
Derby exposes routes
as anExpress middleware on the server, so you can use it alongside otherserver-only Express routes for tasks like uploading files, and you caneven write multiple apps that handle different sets of routes on thesame Express server. For example, you might write a separate admin appor a separate mobile app that doesn’t load all of the code for a desktopbrowser app.
While Derby gives you all of the speed and accessibility advantagesof a more traditional multi-page app, it also creates fully optimizedsingle-page applications that can render any template or route in thebrowser. Client-side routes simply render any links that they canwithout doing a page refresh; you don’t have to call methods on aspecial browser-side routing API. Just put a normal HTML link on thepage, and Derby will render it client-side.
Meteor does not have these features yet, though they recently rewrote their templating engine to use strings so that it is now possible for them to add
. Model-view data bindings
Meteor uses a reactive functional programming approach to updatingtemplates that could potentially work with any template engine. As atemplate is rendered, all of the data that is used to render thattemplate is assumed to be an input to that chunk of the UI. Later, whenthat data changes, the template is re-rendered, and its output iscompared with the DOM. Meteor then patches up the DOM to apply theminimum required changes. Effectively, every single variable andfunction in a template is bound. The big advantage to this approach isits simplicity and ability to support any template language.
In contrast, Derby has its own template language based on Handlebars. Bindings
are declared explicitly, and the HTML of the template is parsed inorder to figure out which parts of the DOM need to be updated. UnlikeMeteor’s, Derby’s bindings are two way; when form elements are bound,the model is automatically updated as users type in text inputs, checkcheckboxes, and select items in drop downs. In addition, it is possibleto bind everything or to optimize the performance of templates by onlybinding what is necessary. Outputting non-bound data may also bepreferred if a developer wishes to update the view via manual DOMmanipulation in special cases. DOM event handlers
It is a relatively minor difference, but Meteor uses CSS selectors onspecific templates, and Derby uses HTML attributes within templates todeclare event handlers. jQuery
have popularized the CSS selector method of scoping event handlers. Knockout
use HTML attributes.
We prefer the HTML markup approach
,because it is more work to figure out what CSS selector matches thecorrect elements, and it is reasonably likely that HTML structure willchange and silently break CSS selectors. With the markup approach, it isless likely that function names will be changed inadvertently, and anerror will be thrown when the function can no longer be found.
Derby also has an innovative approach to event bubbling that is moreefficient and intuitive compared to typical event bubbling. Instead ofbubbling up the entire DOM to the root documentElement for every event,Derby will stop bubbling once it finds an element that is bound to theevent. Like with routes, bubbling can be continued by calling a next() method passed to the event handler. Fibers
Meteor uses the Fibers
extension for Node.js that makes it possible to write synchronouslooking code on the server instead of the more common callback styleused by most Node.js projects. Some prefer this way of writingasynchronous code, others strongly disagree with it. There are a numberof arguments on both sides.
This is very contentious issue at the moment, and we prefer to stay out of it. A very small percentage
of modules in npm are written this way, so we have stuck to the more traditional Node.js style of callbacks. Wrapping it up
You can achieve many of the same things with both frameworks. Bothare powerful tools for implementing features that are very difficult towrite in more traditional web frameworks like Rails and PHP.
Derby has been more focused on making sure it can support advancedfeatures like conflict detection, offline clients, and extremely fastrendering. We are also more focused on compatibility with other modulesin the existing Node.js ecosystem, and we have a permissive open sourcelicense.
Ultimately, we are all trying to create the best tools fordevelopers, and competition can help to breed innovation. We are happyto see other approaches like Meteor
, and Firebase
, because we will all learn from each other. We will end up with better tools, a better web, and better experiences for users.
If you’re interested in what we’re working on, follow us on Twitter