All 22 checks with why-it-matters prose, severity, and cross-references to related audits.
App stores validate icon assets during binary review — a missing density bucket or broken path in app.json causes immediate rejection before a human reviewer ever sees your app. Android's adaptive icon system requires exact pixel dimensions at each mipmap density (mdpi through xxxhdpi); a missing xxxhdpi icon renders as a blurry, pixelated smear on flagship Pixel and Samsung devices. Apple's HIG requires discrete sizes for each display context (home screen, Spotlight, Settings). A single absent size silently fails submission. Beyond rejection, incorrectly sized icons degrade the visual identity of your app on every device class that uses the missing density, directly undermining user trust at the moment of first impression.
Why this severity: Critical because a missing or broken icon file causes automatic app store binary rejection, blocking all users from reaching the app.
mobile-store-readiness.visual-assets.icon-sizes-correctSee full patternAn icon that violates platform visual rules isn't just aesthetically off — it signals to App Store and Play Store reviewers that the app is unpolished and may trigger manual scrutiny. On iOS, pre-rounding corners before export causes a double-rounding artifact: the OS clips the icon again with its squircle mask, creating visible banding on every home screen. On Android, icons with excessive fine detail or thin strokes become unrecognizable at mdpi (48×48), the density shipped on entry-level devices that still make up a significant share of installs in growth markets. Apple's Human Interface Guidelines (apple-hig-app-icons) explicitly call out these failure modes as grounds for rejection. A visually degraded icon undercuts store conversion rates before users open the listing.
Why this severity: High because a non-compliant icon design causes double-rounding artifacts on iOS and illegibility on low-density Android displays, directly harming store conversion and triggering reviewer flags.
mobile-store-readiness.visual-assets.icon-design-compliantSee full patternA missing or undersized splash screen causes two distinct failures: App Store binary rejection (both stores validate that the referenced file exists and meets minimum dimensions) and a jarring white flash during app cold start on devices where the OS cannot scale a too-small image. Expo's required minimum of 1080×1920 matches the baseline 9:16 device ratio; dropping below that introduces pixelation on any mid-range or flagship device. Apple's HIG (apple-hig-launch-screen) and Android's splash screen API (android-splash-screen) both require a launch image to prevent a blank white screen during initialization — omitting it degrades the perceived startup performance that store review teams actively evaluate.
Why this severity: High because a broken or absent splash screen reference blocks app store binary validation and produces a visible white flash on every cold start, immediately degrading first-run experience.
mobile-store-readiness.visual-assets.splash-screen-configuredSee full patternStore screenshots are the primary conversion surface for most app listings — industry data consistently shows screenshots determine whether a user installs after landing on the listing page. Apple App Store requires at least one screenshot per supported device class; Google Play requires a minimum of two. Providing only one, or providing low-resolution screenshots (under 1080px wide), causes store listing rejection and leaves the listing with no visual evidence of what the app does. For context: Apple's screenshot spec (apple-app-store-screenshots) requires 1170×2532 for iPhone 14/15 class devices; submitting a 480×854 screenshot will be rejected outright.
Why this severity: Medium because missing or undersized screenshots cause store listing rejection and eliminate the primary visual conversion driver for new installs.
mobile-store-readiness.visual-assets.screenshots-providedSee full patternAn artificially extended splash screen — one that holds for a hardcoded timer rather than dismissing when the app is ready — violates Apple's HIG and Android's launch screen guidance and is flagged during App Store review as an indication of poor app quality. Beyond rejection risk, every extra second of splash increases abandonment: research on mobile startup performance shows user drop-off begins at 2 seconds and accelerates sharply past 3. A 5-second hardcoded delay loses a measurable percentage of first-run users before they ever see the app. ISO 25010:2011 performance-efficiency applies here directly — launch time is a contractual quality attribute, not a cosmetic preference.
Why this severity: Medium because an artificially extended splash screen signals poor app quality to store reviewers and measurably increases first-run abandonment before users reach the app UI.
mobile-store-readiness.visual-assets.splash-screen-durationSee full patternBundle ID (iOS) and package name (Android) are the permanent, immutable identifiers that link every version of your app, every review, every user install, and every in-app purchase receipt to a single entity in the store databases. A malformed identifier — one that uses uppercase characters, hyphens, or has fewer than three segments — causes binary submission rejection before review begins. Using a generic placeholder like `com.example.app` in production is grounds for immediate rejection. Critically, once an app is published, changing the bundle ID or package name creates a brand-new app listing, breaking updates for all existing users. The Apple Bundle ID spec (apple-bundle-id) and Android Application ID spec (android-application-id) both mandate strict reverse domain notation.
Why this severity: Critical because an invalid or generic bundle ID/package name causes immediate binary rejection, and any post-publication change severs the update chain for all existing users permanently.
mobile-store-readiness.build-config.bundle-id-formatSee full patternCode signing is the cryptographic mechanism that proves your binary was built by you and hasn't been tampered with in transit. Without a valid signing configuration, app stores refuse to accept the binary — there is no workaround or exception. For Android, releasing with only the debug keystore (the default development key) means you cannot update your app once published, because Google Play requires all updates to be signed with the same key. A lost or overwritten keystore permanently orphans your published app, blocking all future updates for every existing user. CWE-798 (hardcoded credentials) applies when keystore passwords appear in committed source — exposing your signing key allows anyone to publish malicious updates impersonating your app.
Why this severity: Critical because unsigned builds are rejected outright by both stores, and a lost Android keystore permanently blocks updates for every existing install.
mobile-store-readiness.build-config.build-signing-configuredSee full patternA production build that points to staging APIs or includes debug tooling exposes real users to test data, unstable endpoints, and developer-only interfaces. More critically, staging endpoints typically have weaker auth, lower rate limits, and no data residency guarantees — a production release hitting a staging backend may log user PII into non-compliant systems. CWE-489 (active debug code) and CWE-200 (information exposure) both apply: redux-logger printing state trees to device logs, or a `localhost` URL falling back to a staging server, creates information exposure paths that violate user trust and may constitute a GDPR Art. 5 processing purpose violation. App store reviewers who discover staging URLs during dynamic analysis can reject the binary.
Why this severity: High because production builds pointing to staging APIs expose real user data to non-compliant endpoints and give reviewers grounds to reject binaries containing active debug tooling.
mobile-store-readiness.build-config.no-debug-in-releaseSee full patternApple and Google enforce minimum OS version floors that increase over time — failing to set an explicit minimum leaves your app exposed to device configurations your dependencies no longer support. Android SDK 21 (Android 5.0), a common implicit default, lacks critical APIs used by modern libraries including SafetyNet, biometric auth APIs, and foreground service types required for background tasks. Google Play enforces a 2-year rolling minimum target-and-minimum policy (android-minimum-target-sdk), rejecting updates that fall below it. On iOS, apps without an explicit `minimumVersion` may be installed on iOS 12 devices where SwiftUI, Combine, and async/await runtime availability differs, producing crashes that reach production users and trigger store review flags from user-reported bugs.
Why this severity: High because an unset or too-low minimum OS version causes crashes on unsupported devices and Google Play actively rejects updates that fall below its rolling SDK minimum floor.
mobile-store-readiness.build-config.min-os-versionSee full patternGoogle Play enforces a hard target SDK deadline: apps that do not target a recent SDK level by the published cutoff date (currently API 34 minimum as of August 2024, with API 35 requirements phased in through 2025) are blocked from updating for existing users and from new submissions entirely. Apple applies equivalent pressure through Xcode version requirements that implicitly raise the minimum deployment target. Targeting an old SDK isn't just a compliance checkbox — it gates your app off of modern platform APIs including scoped storage (Android 10+), exact alarm permissions (Android 12+), and photo picker (Android 13+), all of which affect security posture and user experience on devices that represent the majority of active installs.
Why this severity: High because Google Play blocks updates and new submissions for apps targeting below its rolling SDK deadline, and outdated targets lock out modern security and UX APIs on the majority of active devices.
mobile-store-readiness.build-config.target-os-versionSee full patternApp stores actively audit permission declarations for proportionality — a notes app requesting `ACCESS_FINE_LOCATION` or `NSCameraUsageDescription` without a plausible justification triggers manual review and frequently results in rejection or removal. Under GDPR Art. 5(1)(c) (data minimisation) and CWE-272 (least privilege violation), requesting permissions beyond what your app's core function requires constitutes a legal compliance failure, not just a policy violation. Apple's privacy nutrition label (apple-privacy-permission-usage) surfaces every declared permission to users before install; overly broad permission sets reduce install conversion and increase uninstalls. iOS rejects binaries that declare a permission in `Info.plist` without a corresponding `NS*UsageDescription` string — this is an automated binary validation failure.
Why this severity: Medium because missing `NS*UsageDescription` strings trigger automated iOS binary rejection, and overly broad permission sets expose the app to GDPR Art. 5(1)(c) violations and store reviewer scrutiny.
mobile-store-readiness.build-config.permissions-justifiedSee full patternDivergent app names between iOS and Android fracture brand recognition at the exact moment a user is deciding to install. Reviewers cross-checking listings flag the mismatch as a submission-quality concern, support tickets pile up when users search a store for a name that does not exist there, and paid acquisition attribution breaks because the install surface labels do not match the campaign creative. This operational-readiness defect also leaks into OS-level UI — home-screen icons, notification banners, and share sheets — turning every touchpoint into a trust deduction.
Why this severity: Medium because the inconsistency damages brand trust and discoverability but does not block store approval or break app functionality.
mobile-store-readiness.store-compliance.app-name-consistentSee full patternA valid, publicly accessible privacy policy is a non-negotiable prerequisite for App Store and Google Play submission — both platforms validate the URL during review and reject the binary if the link is broken or the policy is a placeholder. Under GDPR Art. 13, users must be informed of data processing purposes before data is collected; a missing policy means every install is processing personal data without the legally required disclosure. Under CCPA §1798.100, California users have a right to disclosure that cannot be honored without a policy in place. A privacy policy URL that resolves to a 404 or `https://example.com/privacy` placeholder causes immediate submission rejection and, if discovered post-publication, risks app removal and regulatory scrutiny.
Why this severity: Critical because both stores reject submissions without a valid, reachable privacy policy URL, and a missing policy violates GDPR Art. 13 disclosure requirements from the first install.
mobile-store-readiness.store-compliance.privacy-policy-configuredSee full patternApple's Human Interface Guidelines (apple-hig) and Google's Material Design 3 (material-design-3) are not style suggestions — Apple explicitly lists "non-standard navigation or interface" as a rejection reason in App Store Review Guideline 4.2. An Android app using iOS-style navigation (e.g., iOS-mimicking bottom tab bars styled with sharp corners and no ripple effects) will be flagged by Play reviewers as a port that hasn't been adapted for the platform. Beyond rejection risk, users on both platforms have muscle memory for platform navigation conventions — a custom navigation implementation that breaks back-swipe on iOS or back-button behavior on Android produces negative reviews and uninstalls that are directly traceable to this design failure.
Why this severity: High because Apple's guideline 4.2 explicitly cites non-standard navigation as a rejection reason, and platform-alien navigation patterns produce measurable user abandonment and negative reviews.
mobile-store-readiness.store-compliance.design-guidelines-followedSee full patternBoth app stores require content ratings completed through the IARC system (apple-age-ratings, google-play-content-rating) before an app can go live. Without a rating, submissions are blocked at the final publish step regardless of how polished the binary is. A rating also serves a compliance function: apps that collect data from users under 13 must declare this through the rating questionnaire, which triggers COPPA compliance requirements. Incorrectly self-rating an app lower than its actual content (e.g., rating a 17+ app as 4+) constitutes misrepresentation and can result in removal and developer account termination — a disproportionate consequence for what appears to be a configuration step.
Why this severity: High because missing content ratings block the final publish step on both stores regardless of binary quality, and IARC misclassification exposes the developer account to termination for misrepresentation.
mobile-store-readiness.store-compliance.content-rating-setSee full patternApp Store Review Guideline 1.1 (apple-review-guidelines-content) and Google Play's Developer Content Policy (google-play-developer-content-policy) both enumerate content that results in immediate rejection: profanity, graphic violence, sexually explicit content, and hateful speech. Beyond binary-level rejection, content violations discovered post-publication trigger app removal and can result in developer account suspension — losing access to all published apps, not just the offending one. Misleading marketing claims ("100% free" for a subscribed app) are explicitly called out under Guideline 3.1 as deceptive pricing and trigger a separate rejection track. Hardcoded strings in error messages, debug dialogs, and placeholder copy are the most common sources of unintended policy violations in vibe-coded apps.
Why this severity: Medium because content policy violations cause post-publication removal and developer account suspension, while misleading claims in store descriptions trigger a separate deceptive pricing rejection track.
mobile-store-readiness.store-compliance.content-policy-violation-freeSee full patternA thin or error-ridden store description starves the listing of the keywords Apple and Google index for search ranking, directly reducing organic impressions and install conversion. Users who do land on the page churn at the screenshot stage because no feature narrative anchors what they are seeing, and reviewers flag generic copy like "a useful app" as a metadata-quality violation under App Store Review Guideline 2.3.7 and Google Play's store-listing policy. The downstream damage is measurable: lower ASO score, higher CPI for paid campaigns, and avoidable rejections that delay launch.
Why this severity: Medium because poor descriptions throttle discoverability and conversion revenue without blocking store submission outright.
mobile-store-readiness.store-compliance.app-description-optimizedSee full patternMiscategorized apps surface to the wrong user audience in store search and browse — a productivity app filed under Games will appear in game charts and recommendations, driving low-intent installs from users who immediately uninstall when the app doesn't match their expectation. Both Apple App Store (apple-app-store-categories) and Google Play (google-play-categories) use category as a primary browse and search signal; correct categorization directly affects organic discoverability and install conversion rate. Additionally, apps with keywords that don't match their functionality are more likely to be flagged in manual review as keyword stuffing, which can trigger reviewer scrutiny of the entire listing.
Why this severity: Low because wrong or missing categories reduce organic discoverability and may trigger keyword-stuffing flags in manual review, but don't cause binary rejection.
mobile-store-readiness.store-compliance.app-categories-taggedSee full patternNon-semver strings like `1.0`, `v1.0.0-beta`, or `01.00.00` break downstream tooling that parses `app.json` — EAS Update channels, Sentry release matching, crash-report grouping, and CI/CD diff-comparison scripts all assume the `MAJOR.MINOR.PATCH` contract. When the format drifts, release notes collapse into a single bucket, regression bisects miss the breaking commit, and users cannot tell a feature release from a hotfix. Semantic versioning is also the communication channel App Store Connect and Play Console use to render "What's New" prompts correctly.
Why this severity: Low because malformed versions degrade tooling and release hygiene but do not compromise security or user-facing functionality directly.
mobile-store-readiness.version-management.version-semverSee full patternBoth Apple and Google reject any binary whose build identifier is missing, non-integer, or less-than-or-equal to a previously shipped build for the same version string — the upload fails with `ITMS-90062` on iOS or a duplicate-versionCode error on Play Console, blocking the release outright. Without a monotonically incrementing build number, TestFlight cannot route the correct artifact to internal testers, Play Console staged rollouts lose their ordering, and crash reports merge across builds so regressions become untraceable. This is an operational tripwire that delays launches by hours every time it fires.
Why this severity: Low at the code level because fixes are mechanical, but each missed increment costs a full submission round-trip.
mobile-store-readiness.version-management.build-number-incrementedSee full patternVersion history documentation serves two concrete functions: it lets users understand what changed in an update before installing (reducing negative reviews from unexpected behavior changes), and it gives future maintainers a reliable source of truth for which version introduced which behavior. App stores surface "What's New" text in update prompts — an empty or generic "Bug fixes and improvements" entry significantly reduces update adoption rates, which matters for security patches that need broad uptake. ISO 25010:2011 maintainability quality attributes include changeability and testability, both of which depend on accurate version documentation. Without a CHANGELOG, diagnosing regressions across version boundaries requires git archaeology instead of a changelog lookup.
Why this severity: Info because missing version documentation doesn't cause rejection but measurably reduces update adoption and increases future maintenance cost for regression triage.
mobile-store-readiness.version-management.version-documentedSee full patternAd networks that collect user data for personalization require explicit consent under GDPR Art. 6 (lawful basis for processing) and CCPA §1798.135 (opt-out of sale/sharing). An app that imports Google AdMob or Facebook Audience Network without implementing a consent management platform (CMP) is in active GDPR violation from the first European user install — personal data is being processed for ad targeting without a lawful basis. Apple's App Tracking Transparency (ATT) framework makes this enforcement mechanical: iOS 14.5+ requires a system permission prompt before any cross-app tracking, and rejection is automatic if an app uses an ad SDK without requesting ATT permission. Both Apple (apple-review-guidelines-advertising) and Google (google-play-ads-policy) also prohibit intrusive ad placements — ads during checkout or that cover interactive UI elements are explicit rejection triggers.
Why this severity: Low because the check auto-skips when no ad SDK is present, but when ads are found without a consent flow, it represents an active GDPR Art. 6 violation on every European user session.
mobile-store-readiness.version-management.ads-compliantSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open App Store Readiness Audit