A few years ago I was working for a very lean web startup. The team consisted of myself and my father and neither of us could write code. Sure I dabbled a bit in front-end web development but I barely knew enough to be dangerous. Needless to say the engineering work was outsourced to an agency that took a while to ship something that turned out to be pretty far off from what we were expecting. After a few months of frustration I decided to take matters into my own hands.
I took a month off from work (as I knew it) and began to learn the Ruby programming language through a series of online tutorials, trial, and error. Two weeks into my journey I decided to create a prototype of our product using Ruby on Rails. After a few sleepless nights we ended up with a working beta deployed to AWS.
It was time to solve the more difficult problems such as Facebook-style notifications and a front-end that felt like an app rather than a static page. I began to explore the wonderful world of JavaScript. Ember.js and Ember-CLI allowed me to build the front-end as fast as Rails allowed me to build the back-end. I was right at home. So happy with the progress we were making, I nearly got the saying “convention over configuration” tattooed on my back. Ok now just one last feature to check off the list. Realtime notifications.
After some research I decided to go with a Redis pub-sub system with Node.js, Express, and Socket.io. I quickly realized this was much more difficult then typing `rails new`. It felt like eternity to build out a single feature in comparison to the rest of the application. Even though this took longer than I expected, I still found myself falling in love with Node.js. Sure it wasn’t as easy as building a Rails app but the performance was incredible. I began to wonder what if the whole app was built with Node.js. What would that look like? How long would it take? Would it even be worth it? Rather than getting second system syndrome and slowing down I moved on, knowing I’d like to focus on Node.js again someday.
Fast forward to present day. I’m now working for Postlight, an agency in New York City that builds web and mobile apps. At Postlight I have primarily worked with front-end JavaScript frameworks and libraries like Ember.js and React. Doing so has introduced me to ES2015 (ES6) and beyond through Babel. It is amazing to see the amount of progress the JavaScript language has made.
Recently I had the opportunity to work on an open-source project and naturally I followed my pipe dream of a Rails-esque framework for Node.js. Granted a few opinionated Node.js frameworks have popped up over the years but none have satisfied me.
Introducing Lux
Opinionated, Modern, and Fast
A MVC style framework for building highly performant, large scale JSON APIs that anybody who knows the JavaScript language and its modern features will understand.
Lux doesn’t try to be a one-size-fits-all tool. While some frameworks include the kitchen sink, Lux takes a minimal approach. It includes a small set of tools for constructing a JSON API. If you plan on rendering lots of different HTML pages or static assets then Lux is not the right tool for the job. However, if your clients need to consume JSON across multiple platforms such as iOS, Android, or a JavaScript application in a web browser you’re in luck. Lux formats responses to the JSON API specification to make requesting and consuming data a breeze for your clients.
One of the core principles of Lux is to not reinvent the wheel and use the JavaScript language’s standard library rather than creating abstractions that you’ll have to learn. This aspect of Lux is heavily inspired by React and the concept of Minimal API Surface Area. The public Lux API consists of 4 ES2015 classes (Model, Controller, Serializer, Application) and an ES2016 decorator for declaring custom actions in a Controller.
Here’s an example of what a Controller looks like:
https://gist.github.com/zacharygolba/1899f0188b96ba8d6f02
One thing you’ll notice is there are no “actions”. That’s because you get CRUD actions for free by extending the Lux Controller. Built in actions support parameter sanitization, sorting, filtering, and pagination out of the box. If you need to add a custom action then you just write an async function.
https://gist.github.com/zacharygolba/4b97ff8ee87213dd9d55
Wouldn’t it be nice if we could start returning values from functions again?
Lux’s API mirrors the future of the JavaScript language. This makes it easy to use and ultimately easy to hire. Most Node.js frameworks are barely more friendly than the native Node.js HTTP server. For a lot of developers that’s what they want and one of the reasons they reach for Node.js. I’m one of those developers but certainly not all the time. When it comes to building a large API with lots of models, I want some decisions made for me. I’m hoping developers like myself who have a hard deadline and would like to reach for Node.js but end up going with Rails API, Django REST Framework, or something similar can finally have their cake and eat it too.
Performance is an essential part of the psychology behind Lux. Routes are stored and accessed in a Map, not an Array. SQL queries never request more data than they need. Clustering is enabled by default and dynamically configured for the device your application is running on. These small but important details show in this basic benchmark.
The title of this post, Not another Node.js framework, is somewhat of a double entendre. If you look at all the great tools we already have out there for Node.js, one could easily think “oh no not another”. In reality though, Lux is not anything like what we currently have available. It’s not another Node.js framework. It’s not meant to replace Express. Express is multi-purpose and un-opinionated. Often times that level of customization is what people are looking for. The same could be said about something like Sails, which allows you to serve static assets and dynamic HTML. I believe Lux fills a void in the Node.js ecosystem and I hope people find a tool like this as useful as I do.
The road to 0.0.1
The core Lux API is reaching stability and includes many of the features that will be available in the first release. We’re sharing it now so that anyone interested can get their hands on it today.
It will take the support of a strong community for Lux to reach its true potential. If you want to help, feel free to contribute by using Lux for your next project or submitting issues or a pull request on GitHub. The source is roughly 2000 lines of readable JavaScript and I encourage you to check it out for yourself!
Story published on Apr 15, 2016.