Sebastian Sellmair from JetBrains recently showed off a prototype of hot-reloading Compose UI code for deploying changes without rebuilding the project. It looks exciting and I want it to succeed. At the same time, I’ve learned to be cautiously optimistic about hot-reload solutions.
The dream of hot-reloadable android code is old — and frankly, cold. Google has tried this multiple times: their first attempt (Instant Run) was bad and eroded developer trust. Their second attempt (Live Edit + Apply Changes) is apparently doing better, but isn’t very reliable. The best attempt was arguably made by JRebel, who later shut down their product because it wasn’t proving to be financially viable.
Over time, I’ve realized that hot-reloadable code isn’t the ultimate goal — what truly matters are fast feedback loops for validating our changes. Hot reload is just one way to achieve this, but there are plenty of other effective approaches to explore in the meantime.
My pursuit of faster feedback loops is inspired by Bret Victor’s Inventing on Principles talk. It’s quite possibly one of the greatest talks ever and should by seen by every mobile engineer. Bret demonstrates how seeing our changes instantly reflected in the output doesn’t just save time – it fundamentally changes how we create. There’s something magical about having a direct connection to what we’re building.
I’ve experienced this firsthand. At my previous company, some of my favorite moments were spent with designers, fine-tuning animation easings and durations until they felt just right. This rapid iteration is only possible when you can rebuild your demo quickly. The reality is that in larger projects, builds are expensive and can take several minutes to complete, completely killing our creative flow.
Find your fast feedback loops
At Cash App, I’m currently working on a new feature that I haven’t run on a real device in many weeks, and I don’t need to until all the puzzle pieces are ready to fall into their place. Building the full project takes about 2 minutes with incremental changes, which is probably not bad given its size, but waiting for a couple minutes after every change is incredibly unproductive, especially when those 2 minutes turn into 10 if I get distracted by Drake memes on Bluesky.
Instead, I’m relying on fast feedback loops. For iterating on UI, I use paparazzi screenshot tests as my layout preview and unit tests for my presentation/backend code. These take about 7-10 seconds on average to run for Cash App, which is far more manageable. Once I’m satisfied with the code, the generated screenshots can be included in a git pull request to prevent future regressions. Here’s a demo of my workflow:
For complex demos, we use playground Activities in dedicated demo gradle modules that build much faster than the entire project. We have about 35 playground modules in Cash App for various parts of the app. Some of them are built nightly on our CI and made available for designers. These playground can include on-screen knobs for tweaking animations at runtime, something very similar to this:
My favorite way to fine-tune transitions is to build a set of sliders into a prototype to tweak timing parameters on device, as you're using it. pic.twitter.com/JHBBsu0YqF
— Gavin Nelson (@Gavmn) November 20, 2024
For end-to-end testing, we even use a mock version of our retrofit
service so that the app can be run with simulated network responses without needing to talk to a real server.
The bigger picture
The quest for faster feedback isn’t just about UI development – it extends to how your team ships code too. I wrote about this in more detail in my post about how great teams merge fast. The faster you can iterate, test, and ship, the better your product becomes.