These are exciting times to be a front-end engineer at Apteligent. We’ve recently embarked on a ground-up re-architecture of our web application, which started with an evaluation of the technologies we’d use on the new system. This is our first article in a series describing the technologies we chose and why we feel they are right for us.

First, let me give you a little context:

Pain points

Like most web applications of a certain age, ours started as a monolith that we had slowly been carving micro services out of, to the point where the last remnants of the monolith lay in the web application.

And though we had mostly migrated to a JavaScript (Backbone.js) front-end, we were running into a number of problems that we felt necessitated a fresh start:

1. Backbone is a light-weight and flexible framework. But flexibility comes at the cost of having to write a lot of boilerplate. And that makes your code less DRY, easier to screw up, hard to keep consistent, and hard to maintain.

2. A collection of modules that know as little as possible about each other (the best practice in most object-oriented architectures) but have overlapping information needs (common when the modules are parts of the same web page) results in over-fetching of data, accompanied by unnecessary network traffic and back-end system load.

3. The nature of large-scale applications—of necessity built piecemeal—is that it’s hard to reason about the flow of information and events through the application, even with familiarity. Event bindings are distributed across modules and result in poorly-understood, often unpredictable downstream effects of user interaction. We find ourselves fixing different aspects of the same bugs over and over again, each fix uncovering or creating more edge cases. Over time, success in building new features becomes reliant on a combination of institutional knowledge, reverse-engineering, and luck.

Goals

The pain points above make it hard to maintain qualitybuild new features quickly, and, perhaps most importantly, hard to onboard new engineers. These both justify and act as goals for a new application architecture, and in order to achieve these goals, we need to:

1. Simplify the architecture. When you’re building something new, you need to be confident that you’re not breaking something else. That means minimizing and clarifying interdependencies, reducing error-prone boilerplate, making sure complexities are well-documented and, as much as possible, letting common tasks be handled by the framework(s) you’ve chosen.

2. Avoid customizations. The code must be simple enough to be reason-able; it should be relatively straightforward for someone to understand what happens by reading the source. Ideally someone who has only read the official documentation for the framework/library can be assured of success when developing a new feature.That means there are no or very few customizations on top of the vanilla framework. If those customizations exist, they need to be very well documented. The fewer customizations exist, the easier it will be for someone new to the code base to build something without heavy mentoring from someone more familiar with it.

3. Prioritize popularity and good documentation. Reference material on the technologies chosen should be plentiful. Strong official documentation, a sizable community, and a plethora of blog posts/stackoverflow questions should be available to serve as guidance to your team. The obvious caveat here is that the pace of innovation in the JavaScript community is so high that the flavor of the month rarely has adequate documentation. More on this in a later post.

Sharp-eyed readers will have spotted that a certain client-side architecture that’s so hot right now seems tailor-made to address our pain points and goals—and they’d be right. Tune in next week for more.