| Android | iOS |
|---|---|
| Step 1 | Step 2 | Modal |
|---|---|---|
![]() |
| iOS UI | Android UI |
|---|---|
![]() |
![]() |
A production-grade React Native module for verifiable age signals.
Seamlessly integrate with Apple's Declared Age Range API (iOS 26+) and Google Play Age Signals API to meet state-level age verification compliance (e.g., Texas, Utah, Louisiana) without handling sensitive PII yourself.
β οΈ COMPLIANCE NOTICE: Texas SB2420 requires apps to consume age signals from app stores starting January 1, 2026. Similar laws in Utah (May 7, 2026) and Louisiana (July 1, 2026) are also taking effect. This package provides the necessary integration for React Native apps.
Keywords: age verification, texas sb2420, age gate, parental controls, coppa compliance, react native age verification, google play age signals, ios declared age range, app store age verification, react native compliance, child safety, age appropriate design code
- π‘οΈ Privacy-First: Leverages OS-level store APIs. No access to birthdates or PII β only age range classifications.
- π iOS Integration: Native support for
DeclaredAgeRangeframework (iOS 26.0+). - π€ Android Integration: Official wrapper for Google Play
AgeSignalsApi. - π§ͺ Mock Mode: Built-in developer tools to simulate all age scenarios on Simulators and Emulators.
- β‘ Zero Config Mocks: Verification logic works out-of-the-box for development.
- π± Broad Compatibility: Works with any React Native version (0.60+) β uses legacy native module architecture.
graph TD
RN[React Native JS] -->|Standard Interface| Bridge[Native Module Bridge]
Bridge -->|Android| PlayService[Google Play Services]
Bridge -->|iOS| AppleAPI[Apple Declared Age Range]
PlayService -->|Status| Result[Verified / Supervised / Error]
AppleAPI -->|Status| Result
subgraph Privacy Shield
PlayService
AppleAPI
end
npm install react-native-store-age-signals-native-modules
# or
yarn add react-native-store-age-signals-native-modules-
Framework Requirements:
- iOS 26.0+ is required for the
DeclaredAgeRangeAPI to function. - Older versions will return a fallback/unavailable response.
- iOS 26.0+ is required for the
-
Install Pods:
cd ios && pod install
-
Entitlements (Critical):
- You must enable the
Declared Age Rangecapability in Xcode. - Go to Project Target -> Signing & Capabilities -> + Capability -> Declared Age Range.
- Note: This capability typically requires a paid Apple Developer Program membership. "Personal Team" profiles may not support it.
- You must enable the
-
β οΈ Apple API Limitations:- Minimum Range Duration: Age thresholds must create ranges of at least 2 years.
- Example: Thresholds
10, 13, 16work because they create: Under 10, 10-12 (2 yrs), 13-15 (2 yrs), 16+. - Invalid Example:
13, 14, 21would fail because 13-14 is only 1 year. - Common working combinations:
10, 13, 16or13, 16, 18or13, 17, 21.
No manual configuration required. The package automatically bundles com.google.android.play:age-signals.
- Requirement: Device must have Google Play Services installed.
import {
getAndroidPlayAgeRangeStatus,
requestIOSDeclaredAgeRange
} from 'react-native-store-age-signals-native-modules';
import { Platform } from 'react-native';
// π€ Android Example
async function checkAndroid() {
if (Platform.OS !== 'android') return;
const result = await getAndroidPlayAgeRangeStatus();
if (result.userStatus === 'OVER_AGE') {
// β
User is a verified adult
grantAccess();
} else if (result.userStatus === 'UNDER_AGE') {
// β οΈ User is supervised (e.g. Family Link)
// result.ageLower and result.ageUpper are available (e.g., 13-17)
enableRestrictedMode(result.ageLower, result.ageUpper);
} else {
// β Verification failed or unknown
handleError(result.error);
}
}
// π iOS Example
async function checkIOS() {
if (Platform.OS !== 'ios') return;
try {
// Request discrete age signals (e.g. 13+, 17+, 21+)
const result = await requestIOSDeclaredAgeRange(13, 17, 21);
if (result.status === 'sharing') {
// β
User shared their age range
console.log(`Confirmed Range: ${result.lowerBound} - ${result.upperBound}`);
} else {
// β User declined or API unavailable
console.log('Status:', result.status);
}
} catch (error) {
console.error('iOS Signal Failed:', error);
}
}Testing store APIs usually requires signed production builds. This library includes a powerful Mock Mode for development.
// Simulate a Supervised User (Age 13-17)
const mockResult = await getAndroidPlayAgeRangeStatus({
isMock: true,
mockStatus: 'UNDER_AGE',
mockAgeLower: 13,
mockAgeUpper: 17
});Retrieves Android Play Age Signal.
| Parameter | Type | Default | Description |
|---|---|---|---|
config.isMock |
boolean |
false |
Enable to return fake data. |
config.mockStatus |
enum |
'OVER_AGE' |
OVER_AGE | UNDER_AGE | UNKNOWN |
config.mockErrorCode |
number |
null |
Simulate API error code (e.g. -1). |
Request iOS Age Signal.
| Parameter | Type | Description |
|---|---|---|
threshold[1-3] |
number |
Age thresholds to verify. Must create 2+ year ranges. |
- β
Valid:
10, 13, 16β Creates ranges: <10, 10-12, 13-15, 16+ - β
Valid:
13, 17, 21β Creates ranges: <13, 13-16, 17-20, 21+ - β Invalid:
13, 14, 21β 13-14 is only 1 year (API will reject)
Returns: Promise<DeclaredAgeRangeResult>
status:'sharing' | 'declined' | nulllowerBound:number | null- Lower age of user's rangeupperBound:number | null- Upper age of user's rangeparentControls:string | null- Parental control status
| Error Code | Meaning | Solution |
|---|---|---|
| Error 0 | Missing Entitlement | 1. Add Declared Age Range capability in Xcode.2. Ensure you are using a Paid Developer Account. Personal teams often block this API. 3. Real Device Only: This API does NOT work on Simulators. |
| Error -1 | API Unavailable | Device is running an iOS version older than 26.0. |
| Code | Error | Description | Retryable |
|---|---|---|---|
| -1 | API_NOT_AVAILABLE | Play Store app version might be old. | Yes |
| -2 | PLAY_STORE_NOT_FOUND | No Play Store app found. | Yes |
| -3 | NETWORK_ERROR | No network connection. | Yes |
| -4 | PLAY_SERVICES_NOT_FOUND | Play Services unavailable or old. | Yes |
| -5 | CANNOT_BIND_TO_SERVICE | Failed to bind to Play Store service. | Yes |
| -6 | PLAY_STORE_VERSION_OUTDATED | Play Store app needs update. | Yes |
| -7 | PLAY_SERVICES_VERSION_OUTDATED | Play Services needs update. | Yes |
| -8 | CLIENT_TRANSIENT_ERROR | Transient client error. Retry with backoff. | Yes |
| -9 | APP_NOT_OWNED | App not installed by Google Play. | No |
| -100 | INTERNAL_ERROR | Unknown internal error. | No |
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with β€οΈ for React Native developers navigating age verification compliance.



