Building the New Uber Freight App as Lists of Modular, Reusable Components
As Uber Freight marked its second anniversary, we went back to the drawing board to redesign its app. The original carrier app was successful for owner-operators with one or two drivers, but it wasn’t optimized for larger fleets—feedback we were hearing directly from our carrier base. It let carriers find and move freight from point A to point B, but did not support multi-stop loads with multiple pick-ups and drop-offs.
On the engineering side, our team was growing in size. Each piece of technical debt became another unnecessarily complex example in our codebase. Our engineering velocity decreased—simple features took weeks to deploy.
Efficiency was not scaling with increased headcount. We saw the app redesign effort as a great opportunity to rethink how our app was built. Internally, we wanted to ensure that the sum of our team was greater than the individual parts.
Externally, we wanted to quickly give our carriers new features and improved user experiences without compromising quality. In 2016, Uber’s Mobile Platform team rewrote our rider app on a new (now open source) mobile architecture called RIBs. In 2017, the Driver team rewrote our driver app and adopted that same architecture.
In an effort to future-proof the app, The original Uber Freight app was written using the RIBs architecture from the very start. For Uber Freight’s launch in May 2018, the app was built by combining multiple RIBs, structures consisting of routers, interactors, and builders that make up the architecture of Uber’s open source, cross-platform, mobile architecture. It had good code isolation, a well thought out RIB tree with deep scopes, and decent separation of concerns.