RORK LABJP
DEADLINE — From today, August 31, new submissions to Google Play and updates to existing apps must target Android 16, API level 36 or higherSCOPE — Existing apps are not removed. But anything below the requirement stops appearing for users on newer Android versions, so it does not vanish, it just stops reaching peopleEXTENSION — If you cannot make it, an extension can be requested through November 1. Every year some developers reach the deadline without knowing that option existedMIGRATION — What Rork generates sits on React Native and Expo, so raising targetSdkVersion always drags the Expo SDK and its native dependencies along with itTESTING — The time really goes after the build passes. Background execution limits, the permission model, and foreground service type declarations all take effect at onceORDER — A workable sequence: check whether an extension applies, plan the Expo SDK upgrade, then run device regression tests on a minimal build. Doing all three at once hides the causeDEADLINE — From today, August 31, new submissions to Google Play and updates to existing apps must target Android 16, API level 36 or higherSCOPE — Existing apps are not removed. But anything below the requirement stops appearing for users on newer Android versions, so it does not vanish, it just stops reaching peopleEXTENSION — If you cannot make it, an extension can be requested through November 1. Every year some developers reach the deadline without knowing that option existedMIGRATION — What Rork generates sits on React Native and Expo, so raising targetSdkVersion always drags the Expo SDK and its native dependencies along with itTESTING — The time really goes after the build passes. Background execution limits, the permission model, and foreground service type declarations all take effect at onceORDER — A workable sequence: check whether an extension applies, plan the Expo SDK upgrade, then run device regression tests on a minimal build. Doing all three at once hides the cause
Articles/Business
Business/2026-08-31Advanced

After the Google Play deadline: which dormant Android apps to raise, and which to leave at 35

Apps you have stopped updating are governed by a different bar than apps you still ship. Here is how to inventory effective targetSdk across your builds and decide which apps to raise, hold, or retire.

Google Play32targetSdkVersion4Android 164app operations3indie development38Expo191

Premium Article

The first thing I noticed in Play Console was not a number that was growing. It was a row that was not moving.

New installs on an app I had not touched in a long while had gone quiet compared with the previous month. Reviews were fine. Ranking had not slipped. The cause was something I had failed to do, not something that had gone wrong.

Any indie developer running more than two or three apps ends up with uneven update cadence. Some apps get touched monthly. Some go a full year untouched. Annual platform requirements arrive for both, equally.

The awkward part is that "this app is dormant, so the requirement does not apply" is only half true.

The bar for shipping and the bar for staying visible differ by one level

Google Play's target API level requirement is really two rules living under one name. Read them as a single rule and you will misjudge your apps.

RuleWho it applies toLevel after 2026-08-31What happens if you miss it
Submission ruleNew apps, and updates to existing appsAPI 36 (Android 16) or higherYou cannot publish. The upload will not move forward
Visibility ruleEvery app already publishedAPI 35 or higherThe listing stays, but new users on devices running a newer Android will not see it

That one-level gap is the whole point. If you have no intention of shipping again, you do not need 36. You do need 35.

So the decision is not binary. It is three-way: raise to 36 and keep shipping, hold at 35 and protect visibility only, or do neither and accept that new users stop finding the app.

Wear OS and Android Automotive OS apps are outside this requirement. If you own any, take them off the inventory list first so they stop consuming attention.

The authoritative version lives in the target API level requirements on Android Developers. The bar moves every year, so it is worth reading rather than recalling.

Start the inventory from the artifacts on disk, not from the console

Opening Play Console app by app falls apart somewhere past the third app. I switched to reading the build artifacts I already have locally.

The script below walks both AAB and APK files and prints package name, versionCode, and targetSdk as tab-separated rows.

#!/usr/bin/env bash
# List the effective targetSdk of every build artifact under a directory.
# Usage: ./target-sdk-inventory.sh ~/builds
# Requires bundletool (for .aab) and aapt2 (for .apk) on PATH.
set -euo pipefail
 
ROOT="${1:-.}"
# If you keep bundletool as a jar, pass it in:
#   BUNDLETOOL="java -jar $HOME/tools/bundletool-all.jar" ./target-sdk-inventory.sh ~/builds
BUNDLETOOL="${BUNDLETOOL:-bundletool}"
AAPT2="${AAPT2:-aapt2}"
 
printf 'artifact\tpackage\tversionCode\ttargetSdk\n'
 
# -print0 with read -r -d '' survives paths containing spaces.
find "$ROOT" -type f \( -name '*.aab' -o -name '*.apk' \) -print0 |
while IFS= read -r -d '' f; do
  pkg=""; vc=""; tsdk=""
  case "$f" in
    *.aab)
      # set -e is on, so guard the read with || true: one bad artifact must not
      # abort the whole inventory.
      manifest="$($BUNDLETOOL dump manifest --bundle="$f" 2>/dev/null || true)"
      if [ -z "$manifest" ]; then
        printf '%s\t-\t-\tREAD_FAILED\n' "$(basename "$f")"
        continue
      fi
      pkg=$(printf '%s' "$manifest"  | sed -n 's/.*package="\([^"]*\)".*/\1/p' | head -1)
      vc=$(printf '%s' "$manifest"   | sed -n 's/.*android:versionCode="\([^"]*\)".*/\1/p' | head -1)
      tsdk=$(printf '%s' "$manifest" | sed -n 's/.*android:targetSdkVersion="\([^"]*\)".*/\1/p' | head -1)
      ;;
    *.apk)
      badging="$($AAPT2 dump badging "$f" 2>/dev/null || true)"
      if [ -z "$badging" ]; then
        printf '%s\t-\t-\tREAD_FAILED\n' "$(basename "$f")"
        continue
      fi
      pkg=$(printf '%s' "$badging"  | sed -n "s/^package: name='\([^']*\)'.*/\1/p")
      vc=$(printf '%s' "$badging"   | sed -n "s/.*versionCode='\([^']*\)'.*/\1/p" | head -1)
      tsdk=$(printf '%s' "$badging" | sed -n "s/^targetSdkVersion:'\([^']*\)'.*/\1/p")
      ;;
  esac
  # An empty targetSdk means the manifest never declared one. Keep that
  # distinct from a read failure.
  printf '%s\t%s\t%s\t%s\n' "$(basename "$f")" "${pkg:--}" "${vc:--}" "${tsdk:-UNKNOWN}"
done

Expected output looks like this:

artifact	package	versionCode	targetSdk
wallpapers-v210.aab	net.example.wallpapers	210	36
ukiyoe-v180.aab	net.example.ukiyoe	180	35
older-release.apk	net.example.legacy	42	33
broken-artifact.aab	-	-	READ_FAILED

Keeping UNKNOWN and READ_FAILED apart matters more than it looks. Collapse both into a blank cell and "this app never declared a target level" becomes visually identical to "my toolchain is not installed." The first is a real problem with the app. The second is a problem with my laptop. The one thing an inventory must never do is let a real problem hide inside an environment problem.

The same reasoning explains why set -euo pipefail sits at the top while the read commands are wrapped in || true. If a single unreadable artifact halts the run, you lose the count of how many you actually inspected. Decide deliberately where to stop and where to record and continue.

One detail worth knowing: when targetSdkVersion is absent from the manifest, Android treats minSdkVersion as the implied target. Omitting it does not opt you into the newest behavior. Long-dormant projects are exactly where that blank tends to show up.

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
You will be able to tell whether a dormant app is about to stop reaching new users, separately from whether you can still ship updates
You will be able to list the effective targetSdk of every app you own in one pass, straight from the build artifacts on disk
You will be able to record the decision itself so that next year's requirement does not send you back through the same investigation
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

Business2026-08-20
August 31 Means Something Different Depending on Whether You Plan to Ship an Update
Two separate conditions land on Google Play's August 31 date: API 36 to submit an update, and API 35 to stay discoverable to new users. Here is how I sorted six apps, and who actually gets the extension form.
Business2026-08-25
I Split Rork and Claude Code by Who Owns the Build Environment
How to decide between Rork and a terminal coding agent using data from your own repository instead of impressions of generated code. Includes a script that counts which layer your maintenance work lands in, and a check that catches native settings silently disappearing on regeneration.
Business2026-08-11
Four Countries, Not the World: Checking Which of My Six Apps the September 30 Deadline Actually Touches
Android developer verification goes live on September 30, 2026 in Brazil, Indonesia, Singapore, and Thailand. Here's how to decide from your own install data whether that date is urgent for you, and what actually blocks indie developers.
📚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 →