Keep your kitchen organized

The iFood case on Monorepo

Yasmin Benatti
iFood Engineering
5 min readJan 27, 2021

--

Year after year, developers talk about a new framework, architecture, or language. Something sparkles so much joy in the community, that everyone starts talking about it. You can see it in every article or event that you go to, every weekly and keynote.

2019 was not different, and for us, here at iFood, it was all about monorepos and clean architecture.

Before we go into details, let’s travel a few months back to get a clearer picture of the iOS development team.

A growing team

The year is 2015, the team was huge. One brave developer. A new project was created and all the existing code was translated to Swift. One year later, the team would grow to about three developers. More features implemented, more complexity. In 2018, the company reached new heights, and the team completely changed. It went from around 6 developers to over 20 people.

This puts us in a situation where we had to carefully look at how we were doing things. We had more code coming into the version control daily, more features running concurrently, more maintenance to be done. If we didn’t organize and create patterns, we would end up in a very complex chaotic code base.

I wish I could say that we didn’t, but oh boy, did we.

The turning point for us was when a new product was introduced around December 2018. It had tons of code we could share, from business rules to network frameworks to UI components. But we had a huge monolith, full of interdependency, over 10 minutes of local build time, over 40 minutes of CI build time and a couple of frameworks on their own separate repositories.

It was just awful to quickly add and test new features. We started having more and more duplicated code, conflicts of framework versions in each product, and so on.

At the time, the solution was very clear: let’s create a monorepo. We would have all the codebase in one single repository, different frameworks for each piece of code, and no more issues with duplication or versioning.

First things first. How did the monorepo start?

Firstly, we had to organize the monolith and determine owners for each piece of code in there. In February 2019, we did a basic reorganization of folders, putting each feature in a squad subdirectory. A bold pull request with over 2 THOUSAND files changed. It was an audacious move, definitely, but it was extremely necessary and it helped us move forward.

Then, we had to bring those shared frameworks and libraries from separate repositories to the monorepo. Thus, the week after, we created our first two modules using local Cocoapods. One was a network layer framework and the other was a product functionality today known as Loop, our lunch feature. We found the need to give names to things and to create a pattern on how modules were created. This was when the name “microfeatures” entered the scene.

Microfeatures. What are they?

You’ve probably heard the term “microservice”. It’s trendy and backend developers are really into creating individual small services with a single responsibility. Another term becoming very popular is “micro frontend”, which has the same idea as the previous but for frontend developers. Microfeature is just another term for a small module, with a single responsibility that exposes an interface so other modules can interact with it.

We really liked the definition proposed by Tuist as it goes one step further and splits the modules into two types: foundation and product microfeatures.

Foundation µFeature

Modules responsible for a specific task, such as HTTP calls, or UI components, remote configuration workers and so on.

They don’t have any business logic involved, they expose a set of classes or protocols and we can import and use them freely throughout the app. They can be fully tested and compiling time is ridiculously fast.

Product µFeature

Functionalities that your user can see. For example, a login flow or a checkout page, a restaurant’s menu, etc.

They not only have business logic, but also have the screens, the routers, use cases, repositories, and all those Clean Swift and Clean Architecture layers.

Furthermore, they should expose an example app to facilitate development. If you’re working on a product microfeature, you’ll only compile the whole product at integration time.

Managing the monorepo

Things can get very complex pretty quickly in a monorepo, especially when you have over 40 iOS developers working on it. Managing all the modules with local pods was just not suitable for us anymore and so we had to find a tool to do the work for us. And that was when Buck came into the scene.

Around July 2019, we decided to use Buck as the build tool for our project. It was a huge change, but it came in the hands of very few people. We learned a lot about sharing the knowledge during a migration process, and how to not keep most of the expertise focused on a single person. We learnedwe have to communicate, teach and that we need a team to handle developer operations.

Today, we gather most of the information from the Airbnb’s repository cause they are very active in the community and open source most of their adaptations and tools.

One year later… is it still working? Was it a good idea?

We definitely have tons of room to improve, we are polishing the continuous integration stack, applying the usage of caches, automating the creation of µFeatures, removing the final features from the main target and so much more.

Today, we have a team of around 45 iOS developers, over 150 modules, iOS and WatchOS targets and we are preparing to bring a second iOS target to the monorepo. If we can take a lesson from this process it is to share and document everything it’s done. This way, not only you have the history of what was and has to be done, but also a new person can enter the team and get ready to work on the project quite swiftly.

I hope you enjoyed this article and that it has helped you get an idea of how things are done here at iFood and encourages you to do big changes in your own project.

Cheers!

--

--

Yasmin Benatti
iFood Engineering

Howdy! I’m Yasmin Benatti Co-host @ MovileCast 🎙 Host @ Movile Tech Women Slow writer iOS dev @ifooduniverso DIYer whenever possible