Node for Rails developers: using Compound.js

Ruby on Rails developers turning to Node.js may find a soft landing with Compound.js and CoffeeScript

Sagi Isha
Sagi Isha
Sep 30, 2013 · 6 min read

There’s no need to explain how wonderful Ruby on Rails is as a MVC web development framework. It’s mature, well structured, packages (gems) rich, production ready, etc. However performance could be argued, this is not a benchmark post. There’s no need in saying “if you want Rails then stick with Rails”. This post is for developers who decided turning to Node, wishing to enjoy it’s benefits, in this case in a Railsy paradigm.

Node can be used in a diversity of ways, and this is just one simple example. See “The Tip of the Iceberg” at the end of this article in that context. In our context, gladly enough and as mentioned in my earlier post, Node’s community is rapidly expanding and so by now you can find several frameworks that are inspired by Rails. My favorite is CompoundJS, and in the next couple of minutes I’ll try to review it in brief and build together a small To-Do List (what else) using Compound, Coffeescript, Jade, Stylus and AngularJS (databases and tests will be addressed in a different posts).

This use case may be argued a classic Single Page Application with Compound acting as the backend (Restful API, layout and assets) and Angular doing most of the client-side rendering. You should keep in mind this isn’t a Rails tutorial, nor an Angular tutorial, not even a profound Compound tutorial. It’s an intro, relying on the assumption you have sufficient experience that will allow you to leverage these principals into a well structured, highly performing application.

Lastly, you may ask “why should I do this in Node?”, see “The Tip of the Iceberg” at the end of the article to try and answer that. Ready to code? Let’s go.


Getting Started

This post assumes you have Node and NPM installed and ready to go. It also assumes you have sufficient experience with Rails, it’s directory structure, generators, MVC design pattern etc. Otherwise, you may need to do some homework before fully utilizing this text.

I chose to initialize my project using Coffescript. There’s quite a debate going on right now about it, especially with ECMAScript 6 scent in the air, so many Node developers might turn from it, but for the sake of this topic (“Railsy Node” if you like) I want to use in my stack. I also chose to stick with Jade as a template engine, Stylus as a CSS pre-compiler, and neglected a database at this point since it’s a topic on it’s own. Needless to say, Compound (based on the robust and flexible Express.js engine) gives you the complete liberty to choose and integrate any package you prefer, out of the box or as a 3rd party alike.

We’ll start by installing compound globally, and then initiating our project:

[sudo] npm install -g compound
compound init compound-angular-todo —coffee —tpl jade

The result is very much like what you would have expect from Rails to generate. We’ll finalize the setup by installing “node-dev” and installing the other packages required by Compound using `npm install`, just like you’d do with `bundle install` command.

npm install —save-dev node-dev
npm install

We’re ready to run our server. Let’s give it a try:

node-dev server.coffee
Compound server listening on 0.0.0.0:3000 within development environment


Models, Controllers, Views and Routes. You know the drill.

compound g controller tasks
compound g model task description:string completed:boolean created_at:date

Now, for all of our sakes, I’ll make a few shortcuts, likes so:

  • Will remove `public/index.html` static intro page
  • Will include AngularJS in the primary `application_layout.jade` template, and slightly alter it to fit our project.
  • Will define our basic “tasks” routes in `config/routes.coffee`. Notice I’m skipping our regular CRUD paradigm here for two reasons:
    A) Because it’s not written in stone, although considered a good practice. I intentionally approach differently as a preparation for realtime Socket.io implementation.
    B) This is a very simple example and like to keep it as light weight as possible, discarding as much code as I can.
simple routes
  • Will create our basic `tasks_controller.coffee` the handle http requests, bound the the Task model
simple controller
  • I will also create a basic partial skeleton using Jade for my tasks controller, that could be found on `app/views/tasks/index.jade`.
tasks/index.jade angular template
  • Finally I will write a simple AngularJS app that handles the events on our To-Do app. That could be found on `app/assets/coffeescript/ application.coffee`. What going on is basic: loading our tasks list from the server on init, and then updating it on new, edited, completed or removed tasks events.
It’s no wonder you may find Compound directory structure familiar, it’s indeed heavily inspired by Rails

Our app is ready to go. Emulating production (and even in development with less caching) show some sleek response times of 1ms or less per request (as JSON or HTML).

is that fast enough for you?

Pushing to Production

Here’s our Compound-Angluar-Todo app, Rails-style, live: http://compound-angular-todo.herokuapp.com

Review the source code here: https://github.com/sagish/compound-angular-todo


The Tip of the Iceberg

To begin with — I do it because I can. Because it’s educational. Because I like Node, Javascript, Coffeescript, Jade, Stylus and all their comrades and their strengths, and I want to code using them. Because Node reacts faster in development mode (I would argue about production too but I won’t do that without proof and benchmarks), passes TDD faster, and consumes lesser resources (again, all in my personal experience), so I feel lighter developing using it.

But the main reason I would do a Single Page Application using Node is because with a little adjustment we can create a Realtime Application, that receives and responds to events using a scalable implementation of Socket.io (like the wonderful Trello or Asana), that updates without any reloads needed, that is lightweight and growing more efficiently on the server with each update - and we can do it either by following a specially-designed-for-that-cause framework (like Meteor or Derby) or in a way we know and have complete control over (thanks to Express) like a Rails inspired MVC.

Thanks to Udi Wertheimer.

    Sagi Isha

    Written by

    Sagi Isha

    Developer, Yogi, Existentialist; visit me at http://sagiisha.com