Here at Theory and Principle, the team has decades of experience building digital products. Over the years, we have fine-tuned our approach to product development, from process to design to development. While we can often accommodate varying needs from our clients, this discussion explains how we approach a product if given the opportunity to build from scratch.
Why Web Applications?
In a world where everyone is accessing the web on a mobile device (Sources: CNBC and Perficient Digital), why not build a native application? There are many answers to this question, and we’ll only touch on a few of them here. Our CEO, Nicole Bradick, recently did a piece focused on this issue. The first is distribution — it’s hard to get a user to install an app, harder still if it’s something they won’t need every day. Contrast that with a web app, where you just need a user to click a link or type in a URL in order to have a new user. A follow on point here is updating — a web app can be updated at will, whereas a native app has a more complicated release process, and it’s harder to ensure that your users aren’t using an outdated version of your app. The next is cost — if you’re building a native app, you’re really building at least two apps, and probably three. In order to cover the mobile market, you really need a version for both iOS and Android, and in almost all cases, you still need to build a web version for users that can’t or won’t access via a mobile device. Frameworks like React Native lessen this burden some, but it’s still a major undertaking, and requires a nontrivial effort to ensure that your app performs as expected everywhere it’s available.
There are times when a native app makes sense, but in our experience, that’s the exception — most often, a web app is the best choice. So, if we’re going to build a web app, we have to figure out our technology choices. There is a whole universe of options here, but it’s possible to narrow things down pretty quickly by making a few high level decisions. For us, the main factors that led us to our current stack are platform, ecosystem, and developer efficiency, which are all closely related.
Picking an Operating System
Starting at the operating system allows us to narrow things considerably — in the web application universe we’re really talking about Windows vs. Linux. This could be a series of blog posts on its own, but the (very) short version is closed vs. open and free vs. proprietary. Much of the Windows ecosystem is closed source- Microsoft employees are the only ones with access to the source code, and thus the ability to make changes and it also sometimes requires licensing fees (this is slowly changing in the .NET Core era with the advent of the .NET foundation, but it’s a work in progress).
The Linux ecosystem is almost uniformly open source so anyone can get a copy of the source code and propose changes, and it’s normally free to use. As a consequence of Linux being so widely available and free, it has a large user base among developers and web servers (Source: W3 Techs OS rankings) — so much so that even on Microsoft’s Azure cloud platform, Linux is in the majority.
This leads into the second factor mentioned above — ecosystem. Because there are so many developers working on Linux, there are many free packages available that help solve commonly faced problems, allowing us to speed up development times at no cost to our clients.
Languages and Frameworks
There are a number of good Node.js frameworks to choose from, over a dozen ‘major’ offerings at last count. After looking at all of them, and taking many for a test drive, we settled on hapi. It was originally developed at Wal-Mart Labs to handle mobile traffic on Black Friday, so it’s already been proven at scale, and the primary architect of the original OAuth specification (if you’ve ever used your O365 or Google account to log into another website, that’s OAuth), so its security bona fides are unimpeachable. It also falls into the ‘goldilocks zone’ of features for our needs — just the right amount to avoid bloat, without being too light weight and forcing us to reinvent the wheel.
The last decision left to make is our data store. If our app is going to take in information of any kind, it needs to store that data somewhere, usually that’s a database. Today, that can either be a NoSQL variant like MongoDB or a relational database like MySQL or PostgreSQL. NoSQL databases tend to excel at storing largely unstructured data, whereas the relational options are much better at storing structured relational data.
For our purposes, the data is almost always going to be relational — Lawyers have cases which have parties and deadlines and… each of those ‘haves’ is a relationship, and it really helps to have your database engine help you manage those sorts of things. In the end we settled on PostgreSQL, though we still occasionally use MySQL as well. PostgreSQL has a couple of nice-to-have features that pushed it over MySQL for us (in-database support for GIS functionality was a big one), but it’s really hard to go wrong with either of these.
— — — — — — — — — —
Like any development shop, it’s important for us to pick our technologies, master them, and know when it’s time to move the team to something better. While many of our law firm clients run in a .NET environment, and many of our legal tech clients are on Ruby on Rails or Drupal, we’re mostly designing and building systems that are stand-alone applications that integrate with other products at the API level. As a result, those platform differences don’t meaningfully affect our work. Our goal is to leverage the best stack out there for our purposes that provide the best blend of development efficiency, open-source community, and performance for our clients.