Skip to content

support for 16KB page size on Android with NDK27 (27.1.12297006) #54073

@FarouqKrayem

Description

@FarouqKrayem

Description

Description

When building a React Native 0.75.x app on Android with NDK 27.1.12297006 to comply with the Google Play requirement for 16 KB memory page sizes, the generated AAB fails the Play Store pre-launch validation for “16 KB page-size compliance”.

React Native’s native modules (notably react-android and react-native-reanimated) are built via the internal CMake configuration in ReactAndroid/cmake-utils/default-app-setup, which does not propagate custom linker flags such as:
-Wl,-z,max-page-size=16384

Even when these flags are added from the app’s build.gradle via
CMAKE_*_LINKER_FLAGS, the prefab-based native modules appear to ignore them, causing the resulting .so files to remain aligned to 4 KB instead of 16 KB.


Environment

Item Version
React Native 0.75.2
Gradle 8.8
AGP 8.6.1
NDK 27.1.12297006
CMake 3.22.1
macOS Sonoma 14.x
CPU ABI arm64-v8a

Expected Behavior

Building a React Native app with NDK 27 should allow specifying
-Wl,-z,max-page-size=16384 or an equivalent property so that
all native libraries (react_nativemodule_core, react_codegen, etc.) are produced with 16 KB alignment, ensuring Google Play compliance without requiring NDK 28+.


Actual Behavior

Even after passing these flags:

arguments "-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=16384",
           "-DCMAKE_MODULE_LINKER_FLAGS=-Wl,-z,max-page-size=16384",
           "-DCMAKE_EXE_LINKER_FLAGS=-Wl,-z,max-page-size=16384"

React Native’s internal CMake build ignores them, and
the .so files under react-android remain 4 KB-aligned.

---
My build.gradle:
buildscript {
    ext {
        buildToolsVersion = "34.0.0"
        minSdkVersion = 23
        compileSdkVersion = 35
        targetSdkVersion = 35
        ndkVersion = "27.1.12297006"

        kotlinVersion = "1.9.24"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath('com.android.tools.build:gradle:8.6.1')
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
        classpath 'com.google.gms:google-services:4.3.15'
    }
}

apply plugin: "com.facebook.react.rootproject"
---
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
// apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
apply plugin: 'com.google.gms.google-services'
// --- Fix task dependency issue for AGP 8+ ---
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

// Ensure vector icon fonts are copied before lint / package tasks
afterEvaluate {
    tasks.matching { it.name.startsWith("generate") && it.name.contains("Lint") }.configureEach {
        it.dependsOn(tasks.matching { t -> t.name == "copyReactNativeVectorIconFonts" })
    }
}

project.ext.react = [
    enableHermes: true,  // <- set to true to enable Hermes
]


react {
    autolinkLibrariesWithApp()
}


def enableProguardInReleaseBuilds = false

def jscFlavor = 'org.webkit:android-jsc:+'

android {
    ndkVersion rootProject.ext.ndkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    compileSdk rootProject.ext.compileSdkVersion

    namespace "com.evook"
    defaultConfig {
        applicationId "com.evook"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 28
        versionName "1.0.14"

        // ✅ For ndk-build (React Native default)
        externalNativeBuild {
            cmake {
            // keep your existing cppFlags line (C++20 + header shim)
            cppFlags "-std=c++20 -D__cpp_char8_t -include ${rootDir}/android/folly_char_traits_patch.h"

            // ✅ 16 KB page-size compliance for NDK 27
            arguments  "-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=16384",
                        "-DCMAKE_MODULE_LINKER_FLAGS=-Wl,-z,max-page-size=16384",
                        "-DCMAKE_EXE_LINKER_FLAGS=-Wl,-z,max-page-size=16384"
            }
        }
    }
    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }
    
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    
    // ✅ CRITICAL: Package shared libraries as compressed
    // This is REQUIRED for 16 KB page size support
    packagingOptions {
        jniLibs {
            useLegacyPackaging = true
        }
    }
}

dependencies {
    // Remove the noinspection Aligned16KB,comment - it's hiding the problem
    implementation("com.facebook.react:react-android")
    implementation project(':react-native-splash-screen')
    implementation project(':react-native-vector-icons')
    
    implementation platform('com.google.firebase:firebase-bom:34.3.0')
    implementation 'com.google.firebase:firebase-messaging:25.0.1'
    
    if (hermesEnabled.toBoolean()) {
        implementation("com.facebook.react:hermes-android")
    } else {
        implementation jscFlavor
    }
}
---


### Steps to reproduce

Create a fresh RN 0.75.x project.

Set ndkVersion = "27.1.12297006" in android/build.gradle.

Add the CMAKE_*_LINKER_FLAGS arguments as above.

Build with ./gradlew bundleRelease.

Upload the AAB to Play Console → see 16 KB page-size violation.

### React Native Version

0.75.2

### Affected Platforms

Runtime - Android

### Output of `npx @react-native-community/cli info`

```text
System:
  OS: macOS 15.5
  CPU: (12) arm64 Apple M4 Pro
  Memory: 119.28 MB / 48.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 24.7.0
    path: /opt/homebrew/bin/node
  Yarn: Not Found
  npm:
    version: 11.5.1
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2025.09.08.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/lib/ruby/gems/3.4.0/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.5
      - iOS 18.5
      - macOS 15.5
      - tvOS 18.5
      - visionOS 2.5
      - watchOS 11.5
  Android SDK:
    API Levels:
      - "33"
      - "34"
      - "35"
      - "36"
    Build Tools:
      - 34.0.0
      - 35.0.0
      - 36.0.0
      - 36.1.0
    System Images:
      - android-36 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2025.1 AI-251.26094.121.2513.14007798
  Xcode:
    version: 16.4/16F6
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.16
    path: /opt/homebrew/opt/openjdk@17/bin/javac
  Ruby:
    version: 3.4.5
    path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.75.2
    wanted: 0.75.2
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

NA

MANDATORY Reproducer

NA

Screenshots and Videos

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: AttentionIssues where the author has responded to feedback.Needs: ReproThis issue could be improved with a clear list of steps to reproduce the issue.Platform: AndroidAndroid applications.Type: Too Old Version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions