Expo adds AgeRange module wrapping Apple and Google age-verification APIs

c99e1 pts1 comments

AgeRange - Expo Documentation<br>Hide navigation<br>Search or Ask AI<br>⌘ K<br>HomeGuidesEASReferenceLearn

Reference version

ArchiveExpo SnackDiscord and ForumsNewsletter

Expo AgeRange<br>A library that provides access to age range information using Play Age Signals API on Android and Declared Age Range framework on iOS.<br>Android<br>iOS<br>Included in Expo Go

Ask AI

GitHub

npm

Changelog

Copy page

This library is currently in alpha and will frequently experience breaking changes.

expo-age-range provides access to user age range information. It uses Google's Play Age Signals API on Android and Apple's Declared Age Range framework on iOS.

This library allows you to request age range information from your app users to help you comply with age-appropriate content regulations (such as in Texas, USA) and provide age-appropriate experiences in your app.

Limitations

We strongly recommend testing the functionality on a real device, as simulator runtimes may not work as expected.

Installation

TerminalnpmyarnpnpmbunCopy

- npx expo install expo-age-range

If you are installing this in an existing React Native app, make sure to install expo in your project.

Configuration in app config

Setup iOS project

To use the age range API on iOS, you need to build your project with Xcode 26.0 or later. The com.apple.developer.declared-age-range entitlement is required. Add it to your app config file:

app.jsonCopy

"expo": {<br>"ios": {<br>"entitlements": {<br>"com.apple.developer.declared-age-range": true

&]:mt-3 [p+&]:mt-3" data-md="collapsible">&]:rounded-b-none [&_h4]:my-0 [&_code]:mt-px [&_code]:inline [&_code]:bg-element [&_code]:pb-px [&_code]:text-[85%] [&_code]:leading-snug">summary_&]:rotate-0" role="img"><br>Are you using this library in an existing React Native app?<br>pre]:mt-0 [&>*:last-child]:mb-1!">For existing React Native projects, add the entitlement to your project's ios/[app]/[app].entitlements file:<br>key>com.apple.developer.declared-age-rangekey><br>true/>

Usage

Age Range UsageCopy<br>Open in Snack

import * as AgeRange from 'expo-age-range';<br>import { useState } from 'react';<br>import { StyleSheet, Text, View, Button } from 'react-native';

export default function App() {<br>const [result, setResult] = useStateAgeRange.AgeRangeResponse | { error: string } | null>(null);

const requestAgeRange = async () => {<br>try {<br>const ageRange = await AgeRange.requestAgeRangeAsync({<br>threshold1: 10,<br>threshold2: 13,<br>threshold3: 18,<br>});<br>setResult(ageRange);<br>} catch (error) {<br>setResult({ error: error.message });<br>};

return (<br>View style={styles.container}><br>Button title="Request Age Range" onPress={requestAgeRange} /><br>{result && (<br>Text style={styles.result}><br>{'error' in result ? `Error: ${result.error}` : `Lower age bound: ${result.lowerBound}`}<br>Text><br>)}<br>View><br>);

const styles = StyleSheet.create({<br>container: {<br>flex: 1,<br>justifyContent: 'center',<br>padding: 20,<br>},<br>result: {<br>marginTop: 20,<br>fontSize: 16,<br>},<br>});

Additional resources

Play Age Signals API: Android documentation for age signals

Declared Age Range framework: iOS documentation for declared age range

API

import * as AgeRange from 'expo-age-range';

Methods<br>AgeRange.getRequiredRegulatoryFeaturesAsync()<br>iOS 26.4+

Returns the set of regulatory features that the OS reports as required for the current user.

Use this to discover which age-assurance obligations apply.

Resolves with null on iOS earlier than 26.4 and on Android and web — treat<br>null as "unknown" rather than "no features required".<br>Returns:<br>span]:text-inherit!" data-text="true">PromiseAgeRangeRegulatoryFeature[] | null>

AgeRange.isEligibleForAgeFeaturesAsync()<br>iOS 26.2+

Asks the OS whether age-assurance regulation applies to the current user. Apple<br>uses this to signal that the account region is covered by a law such as<br>Utah's or Louisiana's age-assurance requirements, so apps can avoid gating<br>users in jurisdictions where the rules do not apply.

Resolves with true only when Apple confirms regulation applies.

Resolves with false when the OS confirms regulation does not apply.

Resolves with null on iOS earlier than 26.2, and on Android and web.<br>Treat null as "unknown" rather than a definitive false.

Rejects when the request fails — see AgeRangeService.Error<br>for more information. Treat rejection as "unknown" and fall through to requestAgeRangeAsync<br>or your own gating logic.

Recommended pattern: call this first and only prompt the user for their age<br>range when the result is not false. When it is false, the user is outside<br>a regulated jurisdiction and you can skip the age gate entirely.<br>Returns:<br>span]:text-inherit!" data-text="true">Promiseboolean | null><br>*:last-child]:mb-0!">Example<br>try {<br>const eligible = await isEligibleForAgeFeaturesAsync();<br>if (eligible === false) {<br>// Regulation does not apply — no age gate needed.<br>return;<br>} catch {<br>// Treat errors as "unknown" and fall through to the prompt below or your own gating logic.

const ageRange = await requestAgeRangeAsync({ threshold1: 18...

range expo agerange text result error

Related Articles