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.