# uber/RIBs: Uber's Android Architecture Framework, Reviewed

> RIBs is Uber's cross-platform mobile architecture framework, where Router, Interactor and Builder replace the view tree as the organising unit. This review covers what it solves, how to install it for Android, and where it stops being the right choice.

**uber/RIBs** — Uber's cross-platform mobile architecture framework - Android Repository

- Repository: https://github.com/uber/RIBs
- Website: https://eng.uber.com/tag/ribs/
- Stars: 7,940 · Forks: 914
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/uber-ribs

## What RIBs replaces, and who it is aimed at

Most Android architecture guides start from the screen. You have an Activity or Fragment, and the business logic is arranged around it. RIBs inverts that. A RIB is a unit made of a Router, an Interactor and a Builder, and the README states plainly that a RIB does not have to have a view. The application hierarchy is driven by the business logic, not the view tree.

The stated target is mobile apps with a large number of engineers and nested states. Uber describes the architecture as having scaled to hundreds of engineers on one codebase and apps with hundreds of RIBs. That is a claim about Uber's own usage, not a benchmark you can reproduce, but it explains the design: when dozens of people edit the same app, the boundary between features matters more than how quickly a single screen renders.

The README frames RIBs against MVC, MVP, MVI, MVVM and VIPER by drawing a category line: those are patterns, RIBs is a framework. Two consequences follow. Business logic scopes and view hierarchies are decoupled, so you can have a deep business logic tree with a shallow view tree. And state moves through dependency injection rather than through shared view references, which is where the framework's opinions get strong.

## Router, Interactor, Builder: the mechanism in practice

The three components split responsibilities. The Interactor holds business logic and is the piece the README calls out as testable in isolation. The Router handles navigation and attaching or detaching child RIBs. The Builder creates the RIB and wires its dependencies together. Because a RIB can exist without a view, a routing decision can happen in a node that never draws anything, which is how the business logic tree gets deeper than the view tree.

Dependency injection is not an add-on here. The README states that each RIB defines its dependencies and which dependencies it needs from its parent. A parent component that satisfies a child's parent dependencies is passed to the child Builder as a constructor dependency, which is what produces hierarchical DI scoping. Information travels up and down the tree through those dependencies. If your team has not settled on a DI approach, that is the first thing RIBs forces you to decide, not the last.

The README also notes strong opinions about how state should be communicated, naming DI and Rx. That is a real constraint. A codebase that avoids reactive streams will spend its first weeks in RIBs fighting the grain of the framework rather than using it.

The repository layout reflects the split between the framework and its supporting cast. Alongside libraries/ and tooling/, there are demos/ and tutorials/ at the top level, plus a CHANGELOG.md and a RELEASING.md, which is the shape you expect from a project that ships versioned artifacts rather than a sample app.

## Installing RIBs for Android and writing a first RIB

The README's Usage section is short: clone the repository, then integrate using your preferred installation mechanism. For Android, the real instructions are the Gradle coordinates. The README gives the recommended minimum setup as three dependencies, with the annotation processor on annotationProcessor, the Android runtime on implementation, and the test artifact on testImplementation.

```gradle
dependencies {
  annotationProcessor 'com.uber.rib:rib-compiler-test:0.16.6'
  implementation 'com.uber.rib:rib-android:0.16.6'
  testImplementation 'com.uber.rib:rib-test:0.16.6'
}
```

Those three lines are the whole install story as documented. After a Gradle sync you should see com.uber.rib:rib-android on the compile classpath and the compiler running as an annotation processor during the build. The README notes that extension packages exist for Kotlin extensions, Jetpack Compose and Coroutines, but it does not list their coordinates or versions, so you will need to resolve those separately.

For the first RIB itself, the README points at the wiki tutorials rather than inlining a code sample, and it names the tooling section for the code generation plugins. That is the honest path: the repository ships demos/ and tutorials/ directories, and the wiki is where the concepts and the hands-on examples live. Start there before hand-writing Router, Interactor and Builder classes, because the value of RIBs is in the conventions, and the conventions are documented in the wiki, not the README.

## Where RIBs costs you more than it returns

The framework asks for three classes per unit before you have written a line of feature code. For a screen with no children, no routing decisions and no shared state, that is overhead with no payoff. The README's own framing supports this: the design targets apps with many engineers and nested states. If your app has neither, the isolation benefits never materialise and you are left holding the boilerplate.

The dependency injection requirement is the second cost. Hierarchical DI scoping means every RIB declares what it needs from its parent, and the parent must satisfy it. Get that wrong and the failure shows up as a compile-time wiring problem or a missing dependency at construction, not as a runtime crash you can trace from a stack. That is arguably better, but it moves the learning curve to the start of the project.

The cross-platform pitch has a boundary worth noting. The README carries an alert that RIBs for iOS has moved to a separate repository, uber/ribs-ios. So the shared architecture across iOS and Android is real, but it now spans two repositories, and the Android repo you are reading does not contain the iOS implementation. Teams expecting one place to review both platforms should plan for two.

Finally, the README does not document a rollback or migration path off RIBs. There is no guidance on unwinding the hierarchy if you change your mind.

## RIBs compared with MVVM and VIPER in practice

The README's comparison is specific, so it is worth taking literally. MVVM and VIPER are patterns; RIBs is a framework. The practical difference is that with MVVM you typically attach a ViewModel to a lifecycle owner and the view tree defines the app's structure. With RIBs, a node can exist with no view at all, and the tree of nodes is the structure.

VIPER is the closest relative on the pattern side, and the README treats it as a pattern rather than a peer. The distinction it draws is that a RIB does not have to have a view, and that business logic scopes are decoupled from view hierarchies. In VIPER, the View, Interactor, Presenter, Entity and Router set is usually bound to a screen. In RIBs, a Router can attach children without anything being drawn, and the view hierarchy can stay shallow while the logic tree grows.

If you want the same idea on iOS with a different dependency injection story, the README lists Needle as a compile-time safe Swift DI framework and Motif as an abstraction over Dagger for nested scopes. Those are separate projects, not alternatives you drop into an Android build, but they show the shape of the ecosystem Uber built around the same problem.

## Versioning, licence and the cost of keeping up

The Android artifacts are versioned together and published to Maven Central, which is where the README's badge points. Recent releases move in small increments: v0.16.4 and v0.16.5 landed a day apart in September 2025, and v0.16.6 arrived in July 2026. The README pins 0.16.6 in its Gradle snippet, so the documented install and the latest release agree.

The last push to the repository was on 2026-07-15, and the repository is not archived. The CHANGELOG.md and RELEASING.md files at the top level suggest releases are meant to be tracked, so pinning a version and reading the changelog before upgrading is the documented workflow rather than guesswork.

The licence is Apache-2.0. The README includes the full Apache header, which permits use, modification and distribution under the terms stated there, with the usual disclaimer that the software is provided without warranties. That is a permissive licence and it does not impose copyleft obligations on your app. It is not legal advice; if your organisation has a policy on open source dependencies, run it through that.

The upgrade cost is mostly the annotation processor. Because the compiler runs at build time, a version bump can change generated code, and the README's own instruction to keep the compiler and runtime artifacts on the same version is the thing to preserve when you upgrade.

## Conclusion

Adopt uber/RIBs if you are building an Android app with nested screens, several teams touching the same codebase, and a willingness to learn a DI-driven hierarchy before writing features. Do not adopt it for a small app, a prototype, or a team that wants the view tree to stay the primary structure. Verify first that the annotation processor and the Kotlin, Compose and Coroutines extension packages line up with your Gradle and AGP versions, since the README lists them only as available options without pinning versions.

## FAQ

### What is uber/RIBs?

It is Uber's cross-platform mobile architecture framework for Android and iOS, where RIBs stands for Router, Interactor and Builder. The README describes it as designed for mobile apps with a large number of engineers and nested states.

### How do I install uber/RIBs on Android?

The README gives a minimum Gradle setup with three dependencies: annotationProcessor com.uber.rib:rib-compiler-test:0.16.6, implementation com.uber.rib:rib-android:0.16.6, and testImplementation com.uber.rib:rib-test:0.16.6. The README also notes extension packages for Kotlin extensions, Jetpack Compose and Coroutines without listing their coordinates.

### Where can I find an uber/RIBs example or tutorial?

The README points to the RIBs wiki for documentation and a series of hands-on tutorials, and the repository has tutorials/ and demos/ directories at the top level. The README itself does not inline a code sample for building a RIB.

### Is uber/RIBs the same as MVVM or VIPER?

The README treats MVC, MVP, MVI, MVVM and VIPER as architecture patterns and RIBs as a framework. The stated difference is that a RIB does not have to have a view, so the app hierarchy follows business logic rather than the view tree.

### Does uber/RIBs cover iOS as well as Android?

The README carries an alert that RIBs for iOS has moved to a separate repository, uber/ribs-ios. The cross-platform goal is still stated, but the iOS implementation is no longer in this Android repository.

## Sources

- [License: Apache-2.0](https://github.com/uber/RIBs/blob/main/LICENSE)
- [Project website](https://eng.uber.com/tag/ribs/)
- [README](https://github.com/uber/RIBs/blob/main/README.md)
- [Releases](https://github.com/uber/RIBs/releases)
- [uber/RIBs on GitHub](https://github.com/uber/RIBs)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/uber-ribs
