RORK LABJP
DEADLINE — From August 31, every new app and app update on Google Play must target Android 16 (API level 36). Eight days to goEXTENSION — Eligible developers can request an extension through November 1 via a form in Play Console, but the request itself has to be filed before the deadlineEXISTING — Even apps you leave alone need at least API level 35 to stay discoverable to new users on recent Android devices. Standing still quietly cuts off new installsEXPO — Expo SDK 57 moves React Native from 0.85 to 0.86 as a small, one-command upgrade with no breaking changes. React stays at 19.2, same as SDK 56MEMORY — expo@57.0.9 bumps React Native to 0.86.2 and clears the Hermes V1 memory regression that inflated usage in apps importing reanimated or workletsPREBUILD — expo prebuild now clears and regenerates the native directories by default, which collides easily with hand-edited config from your API 36 migrationDEADLINE — From August 31, every new app and app update on Google Play must target Android 16 (API level 36). Eight days to goEXTENSION — Eligible developers can request an extension through November 1 via a form in Play Console, but the request itself has to be filed before the deadlineEXISTING — Even apps you leave alone need at least API level 35 to stay discoverable to new users on recent Android devices. Standing still quietly cuts off new installsEXPO — Expo SDK 57 moves React Native from 0.85 to 0.86 as a small, one-command upgrade with no breaking changes. React stays at 19.2, same as SDK 56MEMORY — expo@57.0.9 bumps React Native to 0.86.2 and clears the Hermes V1 memory regression that inflated usage in apps importing reanimated or workletsPREBUILD — expo prebuild now clears and regenerates the native directories by default, which collides easily with hand-edited config from your API 36 migration
Articles/Dev Tools
Dev Tools/2026-08-23Advanced

Predictive back on Android 16: what to fix before August 31, and what can wait

Targeting API 36 turns predictive back on by default and stops onBackPressed from firing. Here is how I split the work that the deadline actually requires from the work that does not, and how I kept the opt-out from disappearing on the next prebuild.

Android 16predictive backExpo179React Native229config plugin4

Premium Article

After bumping targetSdkVersion to 36, the preview screen looked different when I swiped in from the edge. The screen shrank slightly and revealed what was behind it. That is Android's predictive back animation.

That part I expected. What stopped me was what came next. A swipe I meant as "go back to the grid" was being treated as "leave the app."

The React Native announcement says BackHandler keeps working. And it did keep working. Yet the outcome of the back gesture had changed. It took me a while to understand how both of those can be true at the same time.

"BackHandler still works" and "back navigation is unchanged" are different claims

Apps targeting Android 16 get predictive back enabled by default. Two things change at the OS level.

Before (targetSdk 35 and below)targetSdk 36
onBackPressed() is calledNot called
KeyEvent.KEYCODE_BACK is dispatchedNot dispatched

React Native 0.81 absorbed that change so the JS-side BackHandler keeps firing. The community announcement states that onBackPressed is no longer called, that BackHandler should continue to work, and that if you have custom native back handling you may need to migrate it by hand to OnBackPressedDispatcher.

What I misread was the scope of "BackHandler still works." What keeps working is the handler you registered yourself on hardwareBackPress. Screens where you did not register anything — the ones that hand back navigation to your navigation library — are not covered by that promise.

And React Navigation has not caught up with predictive back yet. Its documentation currently tells you to set android:enableOnBackInvokedCallback to false so the system back gesture behaves as expected. On the Expo side there are reports of stack back navigation breaking under predictive back, with work happening in the newer native stack in react-native-screens.

So the thing that breaks is not the BackHandler you wrote. It is the code you never wrote. That was the most counterintuitive part of this for me: rereading my own source gives you no reason for the failure.

What the opt-out flag stops, and what it does not

android:enableOnBackInvokedCallback="false" is the temporary opt-out Google documents. Its effect is asymmetric in a way that matters for planning.

TargetWith the flag set to false
Predictive back system animationDisabled
OnBackInvokedCallbackIgnored
OnBackPressedCallbackStill called, regardless of the flag

OnBackPressedCallback fires either way. Anything handling back through the AndroidX APIs behaves the same with or without the opt-out. What the flag rolls back is the system animation and the newer callback path.

One more detail. The attribute can live on <application> or on <activity>, and the per-activity value wins. If you set false on <application> but an old true is still sitting on an <activity> from some past experiment, that one screen will not match the rest. I decided to catch that mechanically rather than by memory, which is why the script below inspects both elements.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Decide with confidence that the August 31 deadline only requires the target SDK bump, and that full predictive-back support can be scheduled separately
Sort which of your apps can actually break on back navigation using a script, before you spend an evening tapping through screens on a device
Keep an opt-out from silently vanishing on the next prebuild, so a fix you already made does not quietly revert
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

Related Articles

Dev Tools2026-07-28
Counting what prebuild --clean will erase before you upgrade to Expo SDK 57
A raw diff between two generated ios/ trees showed 649 changed lines; only 3 were real edits. How to count what prebuild --clean erases, and move it into a config plugin.
Dev Tools2026-08-22
Every bulk replace exited zero. The damage was in the lines I did not delete
Run a bulk replace over generated code and the breakage lands on the neighbouring lines, not the matched ones. Here is what broke in a live project, and a dependency-free guard that checks the invariants a replace must preserve.
Dev Tools2026-08-17
When an Expo UI drop-in swap actually removes a dependency
Expo UI went stable in SDK 56 with drop-in replacements for eight community packages. Swapping one import does not always shrink your dependency list. Here is how to decide which swaps actually pay off, straight from the dependency graph.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →