Hello, Nodal — Building Node.js Servers for Everybody

Just under two weeks ago I announced the first big “soft-launch” of Nodal (http://www.nodaljs.com) with a Hacker News post. The response I have received so far has been tremendous, to say the least. With tens of thousands of views on the YouTube tutorials, plenty of interest on GitHub, and a very helpful team of early-adopting contributors, I’m extremely optimistic and excited about the future. (You’re welcome to join us on GitHub.)

To give a high-level overview, Nodal is a Node.js server platform and framework with a bunch of neat bells and whistles designed to make the developer’s life easier. It boasts all of the modern luxuries we’ve grown accustomed to from giants like Rails and Django; PostgreSQL integration, migrations, an ORM, routing, models, controllers, scheduled tasks, a CLI, automatic code-generation, and much more.

For an idea of what Nodal looks like in practice, here’s a controller for a BlogPosts API endpoint:

Amidst the excitement, I felt it would be a good idea to explain some things about the project and why we’re building it. In order for Nodal to be successful, it is very important to me to keep a very open communication line with developers. There are a number of questions I get asked repeatedly, so I thought it best to address them here and give Nodal a little bit of a narrative.


JavaScript’s Explosive Growth

Nodal was born out of a need to address consistency issues in Node.js web server development caused by the explosive growth of the ecosystem. JavaScript is the fastest-growing language (in terms of adoption) the development community has ever seen. It is highly accessible, flexible and robust. I liken it to the English language — far from perfectly designed or architected, but malleable enough to easily pick up and expressive enough to tackle large, complex problems. Because of this, we see a ton of variability in written code. Though the majority of English communication consists of emojis and poorly strung-together half-words, we still have libraries of beautiful essays and novels available. JavaScript is similar. Given optimal reference resources, libraries and structure, we can still train people to be essayists and novelists.

Hello, Nodal

This is where Nodal comes in. The unprecedented rate of change surrounding Node.js has led to libraries written in many different dialects of JavaScript (functional vs. OO, semicolons vs. none, ES5 vs. ES6, promises vs. EventEmitters vs. callbacks). The best of these libraries are extremely powerful and well-tested. The problem is that it’s very hard to write a cohesive novel when you’re trying to mix and match excerpts written with so many different styles.

With the introduction of ES6 (mainly the class syntax and arrow functions) an opportunity arose to use new expressions to create a cohesive, concise dialect of JavaScript and build an encyclopedia around it that would allow any developer — newbie or veteran, back-end or front-end — to join in and begin creating web applications effortlessly.

Value Proposition

Nodal’s codebase is opinionated and follows fairly rigid design patterns and idioms. It does not do this to imprison the developer, but to intentionally restrict them, easing cognitive load and decision fatigue. Nodal makes design and architectural decisions for you, so that you can create products faster.

Nodal also encourages a distributed architecture where API, Branding and Application services are physically separated, with one server (Nodal or otherwise) running for each. Its strongest domain is certainly creating API servers, with built-in standardized API formatting, migrations, and a powerful ORM.

Development Decisions

A common question developers have asked when they look at Nodal’s codebase is, “why didn’t you use [pre-existing solution X] to solve [problem Y]?”. The answer is pretty straightforward — it’s because I primarily view code as a form of communication with other developers. We don’t write code for computers. We write code for ourselves and each other. Computers read binary. Humans read JavaScript. Nodal is a product for humans. With that in mind, it is my intention that Nodal’s core be as easy to read and reason about as the applications built using it. I want Nodal to be accessible to everybody.

Provided this context, throughout development I repeatedly hit roadblocks and snags trying to implement 3rd party solutions. They didn’t fit with the dialect (or rather, design patterns and common idioms) that I was developing. My first big issue was structuring migrations. I began using other solutions, but the amount of code I was writing just to interface with the third-party libraries in a way that I was comfortable with was a nightmare. It was a natural progression from that point. My own migrations led to my own database adapter, which led to my own ORM. The colloquial rabbit hole just got deeper and deeper, until eventually Nodal emerged on the other end.

Distributed Design Philosophy

I mentioned that Nodal encourages a distributed architecture. There are three core tenets to Nodal’s philosophy of distributed design that developers should keep in mind when entering the Nodal ecosystem.

Tenet 1: Software platforms should be modular — ideally one service for each Problem Domain.

A Problem Domain is based on the larger vision of your project (or business) and what you’re trying to accomplish. Roughly speaking, Problem Domains are large, functionally distinct pieces of your platform that accomplish very specific goals. For example, marketing, user acquisition, and branding would be a problem domain (Branding). As would data capture, business logic and CRUD tasks (API). Your user interface + web application for interfacing with CRUD tasks would be a third (Application).

Tenet 2: Each service should be really good at one thing, and only one thing.

Each service should be really good at performing one type of task. For your data capture and business logic, you would have an API service running on a Nodal server. This module should only return API responses. It should never serve static assets. Similarly, your web application service should only worry about serving the web application and not have standalone, one-off server-generated HTML landing pages — let another service handle that.

Tenet 3: Services representing different Problem Domains should exist as separate projects and be as loosely-coupled as possible

This means, but is not limited to, services should have separate code repositories and deployment strategies. If we follow this tenet, we’re creating a distributed, fault-tolerant architecture that isn’t reliant on any single module. If your client-facing web application (single page app) goes down (perhaps due to denial-of-service or buggy code) your API and mobile app can still function perfectly. If marketing wants to outsource development of the branding application to a design firm, give them repository access to that project alone and give them a documented interface for your API.

Nodal can take care of all of these things, but you are discouraged from building monolithic applications using Nodal. Focus on how you can create different services that interface with each other instead of relying on “one web server to rule them all.”

The Future of Nodal

With new contributors jumping in every day, the future of Nodal is bright. We encourage developers to open issues and create pull requests. Things we have planned are Tests as First-Class Citizens, WebSocket integration, GraphQL support and much more. As the community grows we’ll be creating a developer blog and updating our tutorials, introductory guides and API reference docs. Stay tuned, there’s a lot more work to be done.


Enjoy!

Thanks for reading, and I hope you’ll enjoy Nodal. I appreciate any and all feedback, reach out at any time. Collaborators are welcome, so please keep up with Nodal on Github!

To keep up with project development, follow me on Twitter — @keithwhor. You can also visit Nodal’s website at nodaljs.com.


I’m Keith Horwood, you may have previously read my articles about separating concerns across problem domains when building web applications, graph-based recommendation engines, or the DNA sequence alignment algorithm I built in JavaScript.

I’m currently living in San Francisco and working on a new startup. If you happen to see me on the street, say hi!

Follow me on Twitter, @keithwhor.