March 15, 2024
What I learned migrating Nextdoor's feed to Jetpack Compose
Lessons from leading a full Compose migration of a high-traffic Android feed — what worked, what didn't, and what moved the needle.
Migrating a production feed used by millions of people to Jetpack Compose is not something you do in a sprint. Here’s what I learned leading that effort at Nextdoor.
Why we migrated
The Nextdoor Android feed was built on a mix of custom RecyclerView logic and hand-rolled view holders. It worked, but every new feature required touching plumbing that had accumulated years of edge cases. Compose promised declarative UI, better state management, and — critically — easier testing.
The approach that worked
We didn’t do a big bang rewrite. Instead, we used ComposeView inside existing RecyclerView item views, migrating one feed card type at a time. This let us ship incrementally and measure the impact of each change.
The key insight: interop is your friend, not a compromise. Hybrid Compose/View systems run fine in production. Don’t let perfect be the enemy of shipped.
What moved the needle
After full migration, we saw a 4% increase in scroll depth — users were scrolling further into the feed. The smoother rendering from Compose’s optimized diffing and reduced overdraw made the feed feel snappier, which translated to real engagement.
What I’d do differently
Start with the simplest card type, not the most impactful one. We learned the most from low-stakes migrations and applied those lessons to the complex cards. The instinct to start with what matters most is understandable but it’s the wrong call when you’re building new muscle.
More posts on Android architecture and performance coming soon.