At Intuit, I am a full stack engineer on a product called QuickBooks Financing, which is a platform that provides financing options to eligible small businesses. We initially launched our first product in February of 2013, so for those of you can’t math, this is just a little under 3.5 years ago from this time of writing. Our very first product was a web application that was simply a match-making platform that is very similar to Kayak, but with loans instead of plane tickets. Since 2013, we have had many iterations of our product; we have been able to refine our customer problem and we are growing our business to reach any small business within all of our product lines. This includes both our QuickBooks Desktop and QuickBooks Online users.
So how was this built? Well, in the early days, the founding engineers on the team had built our first product under the .NET stack. For what we needed to do at the time, .NET was a great platform! It had given us a full software framework that provided everything that we needed from its pure MVC web framework to its mature services architecture. However, QuickBooks Financing has grown dramatically over the years, and the .NET environment didn’t quite grow or mold itself well into Intuit’s technology ecosystem. Our product has always been a services oriented, single page application experience. As a result, the .NET MVC framework provided us no real benefit for our presentation layer. Not only that, with Intuit's AWS journey, being able to reuse the same Java code as our sister start-up, QuickBooks Self-Employed, and integration with the QuickBooks Online plugin architecture were all additional hurdles we needed to eventually address. Given the growth of our business and the new initiatives we have in place, we had reached a point where we were not able to scale.
So what would most engineers do in our situation?
Rewrite everything of course! That’s right, we rewrote the whole damn platform, and we did it in a little over 4 months with seven engineers.
Planning the rewrite
Intuit has always been a Java house. There are several teams that like to go rogue and build their products under different technologies (e.g. like we did). This wouldn't be a problem if every integration or feature was implemented as an API or service. Intuit is on a journey of everything-as-a-service, but we're not quite there yet. There are still some SDK's and integrations that are only compatible with Java. So as part of the rewrite, the team had collectively decided that for our backend API layer, it should be written in Java. So where does that leave our presentation layer?
For the most part, QuickBooks Financing is a single page application (SPA), so a lot of the work is front-loaded onto the browser. Both the existing Java web frameworks and .NET are very good at handling server-side generated pages. But because we're a SPA, most of the responsibilities of our web server were to simply make sure all of the assets were properly provided to the browser.
Whilst working in the .NET worldm we were running into many issues when building new UI features. These included issues where we needed to manage and load the proper UI experience when we run many AB tests, compiling and bundling the right assets on every build, keeping up with all the copy and UI changes for every single one of our experiences, improving initial page load, and preventing duplication of work. Any new UI feature was a pain in the ass to develop and test. I still have painful scars of how we used to operate.
At its core, these issues could summarized into the following:
- Our developer productivity was hurting
- Modern web design practices had outpaced our current stack, which affected our user experience
If we stayed within the Java landscape in its entirety, we would have run into the same issues as our .NET infrastructure.
Node.js to the rescue!
But whenever you ask someone why they love Node, they will always say, “because you know... event-driven, non-blocking IO!” But let’s be honest for a second, how many of you are actually actually using it for that?