Instagram Direct migrated its Android user interface from the legacy Android View system to Jetpack Compose, creating an AI-native codebase that is easier for AI coding agents to understand, modify, and maintain. According to engineers on the team, the migration reduced UI code volume by 50 percent and token costs per AI agent session by 33 percent.
Designing for AI agents from the ground up
One of the engineers' key claims is that designing an AI-native architecture led to significant wins. Rather than taking a piecemeal approach where agents are prompted to migrate individual components, the emphasis should be on evaluating whether the underlying architecture makes correct implementations easy to produce. As the engineers point out, AI tools often take the path of least resistance, which is likely to introduce subtle bugs, technical debt and performance regressions. Optimizing the codebase for AI means establishing correct architectural boundaries around state management, predictable behavior, and which development patterns make it so that the least resistance path for agents leads to correct, high-quality code, while making poor design decisions hard and expensive to express. Another key principle is minimizing context dependency. Rather than requiring AI agents to rely on codebase-specific knowledge, the team favors established best practices and familiar patterns that help produce more reliable results. The migration was carried through without disrupting the wider team's work, allowing engineers to continue shipping new features. AI-assisted workflows were standardized to promote consistency and ensure alignment with shared architectural conventions and best practices across the team.
With this approach, the Jetpack Compose migration reduced UI code volume by 50 percent, while cutting AI agent execution time by 35 percent, token costs per agent session by 33 percent, and engineer-agent exchanges by 32 percent. A major challenge was ensuring that the migration did not introduce performance regressions. The team focused on three key production metrics: time to interact, the time it takes for a screen to become usable after opening it; time to fully load, the time for all screen content to load; and scroll performance, measuring how smoothly screen contents scrolls. These metrics are tracked at runtime in production, making it possible to run A/B tests comparing the migrated Compose UI against the legacy UI and evaluate the performance impact of this effort.
Abstraction and runtime switches
One significant finding for engineers was that performance could not be assessed reliably until entire screens were ported to Compose, eliminating any remaining legacy Views that could distort performance measurements. This means Compose UI components should be abstracted away from the framework they are enclosed in while still being compatible with both RecyclerView and LazyColumn at the same time. Equally important is the ability to switch between the two at runtime via feature flags, to enable A/B testing. Eventually, the team replaced the legacy RecyclerView, initially retained as a container for the new Compose-based composables, with LazyColumn, Compose's native solution for efficiently rendering scrollable lists. As a final note, the migration also improved startup performance in other areas in the app. This was partly because Compose has a runtime warmup cost that is incurred only once per app session, allowing other Compose-based screens to benefit from the runtime already being initialized rather than paying that cost again.