Unboxing: Meteor

Dev  

Originally posted on Box UK website: https://web.archive.org/web/20121217061319/http://www.boxuk.com/blog/unboxing-meteor

Meteor

Three years ago, Ryan Dahl gave to the world the first version of server-side software with which to build web applications using JavaScript. Built on top of Google V8 with asynchronous uses in mind, Node.js has quickly grown a fantastic and a lively community. However, even as the ecosystem became more and more mature and produced a fantastic pool of open-source libraries, most developers around the world were still figuring out if this platform was to be trusted for enterprise applications.

Whether you like it or not, let's face it; Node.js is not bleeding edge any more. A lot of developers are now comfortable with functional JavaScript, having more than one generation of web framework behind us. Alternatives, as well as good practices, have been provided to avoid (or embrace) callback spaghetti code, and with NPM more than 18,000 packages are available to use through the same pattern that you already use for your front-end JS code (CommonJS).

Furthermore, something is in the air. The community is going one step forward into maturity. Yeoman, Brunch, Derby, RailwayJS, Yahoo Mojito, Meteor, Geddy, Tower, SpaceMagic, Firebase and a bunch of others projects (sorry if I’ve missed yours) are attempting to provide fully stacked JavaScript frameworks. If the chosen paths are different, the goal is clear: bind together the best libraries and make it easy to build something fun and powerful.

In this blog post, we will look closely at Meteor (Now in version 0.5) which was praised on Hacker News a couple of months ago.

What is it?

The goal of Meteor is to provide a simple and fast way to develop web applications. Let's see if it is as good as it seems.

Getting to grips

Before you open the command line, let's see how it works.

The first noticeable thing is that you don't have to have any knowledge of Node.js and other related server-side libraries. Meteor provides a convenient abstraction to let you focus on your core features. However, if you are used to the Node stack and like to have your hands dirty, then it could be difficult for you to stick to doing things in this way.

All your JavaScript, everywhere

Forget about Require.js; the framework handles it for you. In fact, you can write any piece of code almost anywhere. You have a few rules explaining which directories go to the server and which go to the browser (or both), as well as a convenient statement to explicitly run code on the server or the client:

  if (Meteor.isServer) {
       //Server code
  }

  if (Meteor.isClient) {
       //Client code
  }

I can't say it's the best approach for long-term projects, but to quickly bootstrap something, it's quite handy. The best side effect of this is you can easily share code between the client and the server, and easily switch from one strategy to another.

Communication is the key

At runtime, the communication between the server and the client is made using Socket.io... But it's not mandatory to know that. Meteor will hide the logic and let you synchronise your data through a publish/subscribe system.

Given a collection on the server:

  var Rooms = new Meteor.Collection("rooms")

You can tell Meteor how and what to publish to all subscribers on a specific channel:

  Meteor.publish("all-rooms", function () {
       return Rooms.find(); // everything
  );

Then, given another collection in the browser:

  var Rooms = new Meteor.Collection("rooms")

You can subscribe to this event:

  Meteor.autosubscribe(function () {
     Meteor.subscribe("all-rooms");
  });

The syntax is a bit weird, but Meteor knows from the name of the collections ("rooms" in this case) what to synchronise, and how to do it via the publish/subscribe methods. That way, you can simply do:

  Rooms.find()

And the client-side collection will be hydrated correctly. Even better, the "autosubscribe" method is here to give some kind of reactiveness. That mean if you update the server-side collection at any time, the subscribe event will be fired again and the collections will be synchronised, seamlessly.

All your base are belong to us

By using the "Meteor.Collection"s, all data is smoothly and asynchronously stored in a MongoDB instance.

On the client-side, you can also use:

  Session.set("key", value);

And

  Session.get("key");

To store and retrieve values to/from a local storage.

Can I haz ze same with templates?

If you have already used libraries such as AngularJS or Ember you will probably ask for the same reactiveness about displaying this data. And that’s exactly what Meteor gives you.

It's closer to Ember than Angular as it uses Mustache and has the same "dependencies" logic concerning computed values.

If you have a Mustache template like this (anywhere in your HTML):

  <template name="rooms">
       {{#each room}}
        <div>{{id}}: {{name}}</div>
     {{/each}}
  </template>

Meteor exposes all the template’s elements in JavaScript variables so you can update it programmatically:

  Template.rooms.room = Rooms.find();

When you change the value of a template member (or the value of a dependent variable), the corresponding template is refreshed.

Not sure I understand it well…

Not sure I was clear enough either :) But ultimately, if you embrace the Meteor model, you can have a nice event-driven workflow for your data. Almost for free!

Data on the server -> Data in the browser -> UI updated

Going Deeper

Command line all the things!

As it should be for every developing tool, Meteor comes with a command line utility that helps you a little with your work. For example:

  • meteor create : creates the files needed for an empty project.
  • meteor run: constructs a temporary environment and runs your project into a Node.js container. (Your page is then LiveReloaded)
  • meteor mongo: launches a mongodb shell to execute query against the local database.
  • meteor deploy: lets you upload your application in the Meteor hosting domain name.
Security

Freshly baked for version 0.5, Meteor now provides a way to authenticate users. It's a simple solution but as always, that comes with the downside of less freedom and customisation.

Just put this in one of your templates:

  {{loginButtons}}

And you're done. Basically. Meteor takes care of the UI, the session, the storage, everything!

With a little configuration you can have login/password authentication and also third-party logins like Github, Twitter, Facebook, etc...

When the user is logged in, you can access their details by using:

  Meteor.user()

Feel free to look at their documentation, which is not bad at all: http://docs.meteor.com/#meteor_user

Under the Hood

While the core of Meteor is built on top of Node.js, the framework makes massive use of a library called Fibers. I am not exactly sure about the full consequences of this, but it is something that you need to be aware of when using Meteor.

I’m sure other blog posts out there probably explain this better than me but, in summary, it uses the concept of co-routines to transform the asynchronous nature of Node.js into a synchronous, threaded system.

It's an internal choice, so there is no direct impact on your code, and I don't even know the real impact on the scalability. But the Meteor developers are clever guys and I can guess that Fibers suits their model better.

Extendability

Meteor lets you add packages via the command line:

  meteor add <package>
  meteor remove <package>

For example, you can add the ability to understand Coffeescript:

  meteor add coffeescript

But for some reason, maybe because of Fibers, you can't directly use the packages of NPM. There is perhaps a good reason for this but it is the main caveat that I have against using Meteor. It's a real brake to faster developments as you have to write from scratch what other people already did a hundred times better.

The only way to extend the framework during this beta phase is to use a project called Meteorite, which is basically the Meteor command tool + Atmosphere, a third-party repository of packages.

  mrt add yaml

Want to know more?

Look at the source, Luke

I built a small web application that displays the Coderwall badges of a given username.

The code is here: https://github.com/athieriot/tabularasa. You can execute "meteor run" after cloning the repo.

But during the beta phase of Meteor, they provide a free hosting solution, so you can also test it there: http://tabularasa.meteor.com/

You will find that there are only 30 lines of Coffeescript and 65 lines of HTML to build a system that fetches a REST API and automatically updates the view. It's maybe not so rare these days, but I am very impressed anyway.

Conclusion

Meteor offers a great JavaScript stack if you want to build a small application and focus only on your business. In most cases, it provides you with what you would have done by yourself anyway when using Node.js: data binding, Socket.io, a templating system, authentication, LiveReload, etc... Even if it's a beta version and lacks some features (like the ability to test your application), this product is very stable and relies on trusted libraries.

Unfortunately, it comes with a big downside: Meteor is kind of a black box that you can barely extend. You can't use NPM, it's difficult to customise the generated application, and the usage of Fibers makes it even harder to create add-ons.

However, as this project is in heavy development, I recommend it for those who want to bootstrap a small proof-of-concept, or play with server-side JavaScript (and the Node.js API) before jumping in at the deep end.


comments powered by Disqus