Mobile Architecture
at Scale
Why and how we built a new
architecture used by hundreds of
engineers, all in one codebase
18 Jan 2018
Gergely Orosz, Engineering Manager,
Payments, Uber
Engineering at Uber
Payments Experience
• Rider
• Driver
• Cash
• Platforms
Developer Experience
• Mobile
• Backend
Amsterdam HQ
• ~100 tech (dev,
design, DS, PM, UX)
• ~700 total
Engineering @ Uber
Amsterdam
Payments Experience
• Rider
• Driver
• Cash
• Platforms
Developer Experience
• Mobile
• Backend
Engineering @ Uber
Amsterdam
Motivation Architecture Scaling an
architecture in
practice
Motivation Architecture Scaling an
architecture in
practice
â—Ź History
â—Ź Architecture growth
â—Ź Goals of the rewrite
Motivation
Initial Team
Team Growth
Over 100 mobile engineers?
Request a ride
Fare split
Cash
Uber for Business
Credit card rewards points
Promotions
Promotions
Safety
Over 10 ways to pay
Scheduled
rides
Drive for Uber
Uber Eats, Freight,
Self-driving vehicles...
Experimentation
80 countries,
600 cities
Performance
Cash
Instant payments
Maps & navigation
uberPOOL
Driver incentives
App health
Developer tools
Networking
Feed cards
Driver experience
Driver recognition
Airport pickup
Uber Family
Beacon
Campaigns
Fraud EATS app
Courier experience
Shipper experience
Restaurant experience
App Growth
App Growth
App Growth
Let’s just change everything
1. History
2. Architecture growth
3. Goals of the rewrite
Motivation
Architecture Growth
LoggedIn
Activity
ProductSelection
Controller
Menu
Controller
Location
Controller
Custom
View
Custom
View
Sub
Controller
Architecture Growth: State
Architecture Growth: State
LoggedInState
LoggedIn
Activity
ProductSelection
Controller
Menu
Controller
Location
Controller
Custom
View
Custom
View
Sub
Controller
Architecture Growth: State
... ...
LoggedInState
LoggedIn
Activity
ProductSelection
Controller
Menu
Controller
Location
Controller
Custom
View
Custom
View
Sub
Controller
LoggedIn
Activity
Architecture Growth: State
... ...
LoggedInState
LoggedIn
Activity
ProductSelection
Controller
Menu
Controller
Location
Controller
Custom
View
Custom
View
Sub
Controller
LoggedIn
Activity
LoggedIn
Activity
â—Ź Number of engineers
â—Ź Understanding how the app works
â—Ź Shared state
â—Ź Modifying the app
Our Biggest Problems
Shared State
class DriverIsOnTheirWayToaster {
var isOnTripAndHasNotBeenNotified:Boolean = false
fun onCreate(stateStream: TripStateStream) {
stateStream
.state()
.subscribe({ (trip, driver) ->
if (trip == TripState.ON_THEIR_WAY) {
isOnTripAndHasNotBeenNotified = true
showToast(driver!!.name)
} else if (trip == TripState.ON_TRIP) {
isOnTripAndHasNotBeenNotified = false
}
})
}
}
class DriverIsOnTheirWayToaster {
var isOnTripAndHasNotBeenNotified:Boolean = false
fun onCreate(stateStream: TripStateStream) {
stateStream
.state()
.subscribe({ (trip, driver) ->
if (trip == TripState.ON_THEIR_WAY) {
isOnTripAndHasNotBeenNotified = true
showToast(driver!!.name)
} else if (trip == TripState.ON_TRIP) {
isOnTripAndHasNotBeenNotified = false
}
})
}
}
class DriverIsOnTheirWayToaster {
fun onCreate(driver: Driver) {
showToast(driver.name)
}
}
Modifying the App
... ...
LoggedInState
LoggedIn
Activity
ProductSelection
Controller
Menu
Controller
Location
Controller
Custom
View
Custom
View
Sub
Controller
LoggedIn
Activity
...
LoggedIn
Activity
......
ProductSelection
Controller
Location
Controller
Menu
Controller
1. History
2. Architecture growth
3. Goals of the rewrite
Motivation
â—Ź Constraints
â—‹ Native development
○ Independent iOS & Android™ codebases
â—Ź Opportunities
â—‹ Mobile Platform team
â—‹ iOS & Android monorepos
Constraints & Opportunities
â—Ź Isolation & testability
â—Ź Developer productivity
â—Ź Support continued growth for years
â—Ź 99.99% reliability of core flows
â—Ź Monitoring as a first class citizen
â—Ź De-risk experimentation
Rewrite Goals
Rewrite Goals
Image by Tsahi Levent-Levi
Android is a trademark of Google LLC.
Rewriting the Uber App
January June August November
Core architecture, framework & tooling
Core flow
Everything else
RIBs Architecture
What We Built
Application Framework
Scoping
Routing
Business-logic driven
Dependency management
Open source
Monitoring
Components
Code generation
Reactive data flows
Testability
Experimentation
Plugins
Networking
Storage
Location services
Analytics
Logging
UI components
Motivation Architecture Scaling an
architecture in
practice
â—Ź Application state
â—Ź Dependency scopes
â—Ź Designing of RIBs
Architecture
The state management problem
State Tree
Root
LoggedInLoggedOut
Onboarding Menu Request
Home
ShortcutsFeedCard
Location
Editor
OnTrip
...
State transitions
RIBs
Root
LoggedOut
Backend
LoggedIn
Login request
Session response
LoggedOut
State Tree
State tree drives the views
Root
LoggedInLoggedOut
Onboarding Menu Request
Home
ShortcutsFeedCard
Location
Editor
OnTrip
...
Request
Home
LoggedOut
State Tree
State tree drives the views
Root
LoggedInLoggedOut
Onboarding Menu Request
Home
ShortcutsFeedCard
Location
Editor
OnTrip
...
â—Ź Application state
â—Ź Dependency scopes
â—Ź Designing of RIBs
Architecture
Dependency Scopes
Application driven by business logic
Root
LoggedInLoggedOut
Onboarding Menu Request
Home
ShortcutsFeedCard
Location
Editor
OnTrip
...
LoggedOut
Dependency Scopes
Application driven by business logic
Root
LoggedInLoggedOut
Onboarding Menu Request
Home
ShortcutsFeedCard
Location
Editor
OnTrip
...
Dependency Scopes
Application driven by business logic
Root
LoggedInLoggedOut
Onboarding Menu Request
Home
ShortcutsFeedCard
Location
Editor
OnTrip
...
â—Ź Application state
â—Ź Dependency scopes
â—Ź Designing RIBs
Architecture
â—Ź MVC, MVP, MVI, MVVM
â—Ź VIPER, (B)VIPER
Popular Mobile Architectures
MV*
Model
Controller
View
Model
Presenter
View
Model
ViewModel
View
Model
Intent
View
Input
Input
Input
Input
MVC
MVI
MVP
MVVM
VIPER
Interactor
Business logic
Router
Route between screens
View(Controller)
Layout & animation
Presenter
UI logic & respond to
user inputs
Entity
â—Ź View tree drives the app hierarchy
â—Ź Business logic & view trees are tightly coupled
â—Ź Deep scope hierarchies supported only based
on view nesting
MVC, MVP, MVVM, MVI & VIPER
(B)VIPER
Making VIPER components reusable
Interactor
Business logic
Router
Route between screens
View(Controller)
Layout & animation
Presenter
UI logic & respond to
user inputs
EntityModule Builder
Creates VIPER classes
RIBs
Interactor
Business logic of the app
(aka “the brain”)
Router
Routes between RIBs
View(Controller)
Layout & Animation
Presenter
(Optional)
Translation Logic
View model
UI event
Data model
Business logic calls
Routing calls
Builder
Creates RIB units
Router Interactor Builder
RIBs
Presenter View
Request
Home
LoggedOut
State Tree
State tree drives the views
Root
LoggedInLoggedOut
Onboarding Menu Request
Home
ShortcutsFeedCard
Location
Editor
OnTrip
...
Demo
Data flow with RIBs
RIBs
Interactor
Router
View(Controller
)
Presenter
(Optional)
Builder
Interactor
Router View(Controller)Presenter
EntityModule Builder
RIBs
(B)VIPER
Data flow with RIBs
ServiceModel Stream Pushes state onto
Service callsData model
Non-state modifying
responses
Logic calls
The Internets
Interactor
Router
View(Controller)Presenter
UI event
View model
Push/pull
Data model
Routing calls
Viewless RIBs
Viewless RIBs
ServiceModel Stream Pushes state onto
Service callsData model
Non-state modifying
responses
Logic calls
The Internets
Interactor
Router
View(Controller)Presenter
UI event
View model
Push/pull
Data model
Routing calls
Attach / detach child RIBs
Demo
Viewless RIBs - demo
Motivation Architecture Scaling an
architecture in
practice
â—Ź Adopting a framework with
a large team
â—Ź Why RIBs worked
â—Ź Summary
Scaling an architecture in practice
Adopting a framework with a large team
â—Ź Code generation
â—Ź Onboarding
â—Ź Enforcing (architecture)
patterns
Adopting a framework with a large team
Rails for architecture & code
Code Generation
Android (IntelliJ, Android Studio) iOS (XCode)
Open sourced
Onboarding
â—Ź How long does it
really take to learn?
â—Ź Documentation
â—Ź Tutorials
â—Ź Encourage
contribution
Open sourced
â—Ź Lint rules
Enforcing (architecture) patterns
â—Ź (Blocking) code
reviews
Enforcing (architecture) patterns
â—Ź Process for change suggestions (RFC)
â—Ź Lint rules
â—Ź (Blocking) code
reviews
â—Ź Code generation
â—Ź Onboarding
â—Ź Enforcing (architecture)
patterns
Adopting a framework with a large team
â—Ź Have a clear owner
â—Ź Adopting a framework at scale
â—Ź Why RIBs worked
â—Ź Summary
Scaling an architecture in practice
â—Ź 3 apps, more than 200 developers
â—Ź More than 600 RIBs, reused within & across apps
â—Ź Less than 300 lines of code / class for most RIBs
â—Ź All business logic well unit tested
â—Ź Open sourced
How RIBs worked out
â—Ź Long dependency injection chains
â—Ź Too much (boilerplate) code
â—Ź [iOS] RIBs incompatible with plain Views
Feedback from engineers after a year’s usage
â—Ź Does your app have lots of non-visual state?
â—Ź Do you have a (fast) growing iOS & Android app/team?
â—Ź Do you have the bandwidth to invest in a new architecture?
Is RIBs for you?
â—Ź Adopting a framework at scale
â—Ź Why RIBs worked
â—Ź Summary
RIBs in practice
Motivation Architecture Scaling an
architecture in
practice
Gergely Orosz
Engineering Manager, Uber Amsterdam
@GergelyOrosz
eng.uber.com
Thank you
uber.github.io
Proprietary and confidential © 2017 Uber Technologies, Inc. All rights reserved. No part of this
document may be reproduced or utilized in any form or by any means, electronic or mechanical,
including photocopying, recording, or by any information storage or retrieval systems, without
permission in writing from Uber. This document is intended only for the use of the individual or entity
to whom it is addressed and contains information that is privileged, confidential or otherwise exempt
from disclosure under applicable law. All recipients of this document are notified that the information
contained herein includes proprietary and confidential information of Uber, and recipient may not
make use of, disseminate, or in any way disclose this document or any of the enclosed information
to any person other than employees of addressee to the extent necessary for consultations with
authorized personnel of Uber.

Mobile Architecture at Scale