By Harshad and Nadine

Writing an app is pretty easy. All you need is an idea, a design, and an API. This is what most apps are. And this is what GO-JEK was once upon a time.

We started simple: with only three products. The features were limited, the codebase was small, and so was our team. Over the years, we added a dozen more products. Our codebase grew to over half a million lines of code and the team, to over 20.

While this is amazing progress, there are also some problems unique to a massive Swift codebase. One of them being — torturously long compile times.

You could grab a snack, go to the restroom, and watch an episode of Friends, while GO-JEK built.

It makes for a funny anecdote now, but in reality, we were suffering. We were wasting half of our day compiling the app. At times we took weeks guessing which state mutation from which thread is causing that annoying weird crash. This was the time when simple text changes took 30 minutes to verify. It was exasperating.

We tried to hack our way through this by removing type inference, buying faster computers, adding cryptic compiler flags we didn’t really understand, or praying for a Xcode update which magically fixed it all. But this would only get us so far. We needed a permanent solution. The answer — experimenting with different architectures.

GO-JEK went through wave after wave of architectural trends. We implemented and re-implemented parts of our codebase using different patterns like MVVM, MVP and even VIPER.

While these popular patterns helped us structure our products internally, we couldn’t apply them to structuring the GO-JEK app as a whole. The solution to our long compile times was simply compiling less code at a given time.

Did we really need to compile all that code?

Say you’re working on GO-RIDE. Why should you need to compile GO-FOOD or GO-SHOP? This is how we started tackling the problem. The aim was to only compile the product the team was currently working on.

The first step to achieving this was separating product code from GO-JEK’s main codebase. This means all GO-RIDE code goes into its own framework, in its own repo. Now repeat this for every GO-JEK product. Compiling each product framework is almost instantaneous, simply because we were compiling 1/20th of the code.

We now have all GO-RIDE screens in one framework. But how do we place a GO-RIDE order without the GO-JEK home screen?