Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/thin-spoons-trust.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/expo': minor
---

Add iOS and Android APIs for biometric trusted-device enrollment, sign-in, availability, listing, and revocation, including structured native error codes and forward-compatible resource values. Add native authentication-flow readiness state for safely gating authenticated content and support configuring the Face ID permission message through the Expo config plugin.
41 changes: 41 additions & 0 deletions packages/expo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,47 @@ You'll learn how to create an Expo application, install `@clerk/expo`, set up yo

For further information, guides, and examples visit the [Expo reference documentation](https://clerk.com/docs/references/expo/overview?utm_source=github&utm_medium=clerk_expo).

### Biometric trusted devices

Biometric trusted-device enrollment and sign-in are supported in development builds on iOS and Android. Android requires Android 9 (API 28) or later and an enrolled Class 3 biometric.

Trusted-device operations preserve Clerk API and native biometric error codes. Use `isTrustedDeviceError(error)` to safely inspect `error.code`; unrecognized codes and resource values remain available for forward compatibility.

#### Face ID on iOS

Apps that use Face ID for trusted-device enrollment or sign-in must provide `NSFaceIDUsageDescription`. You can have the Clerk config plugin add it during prebuild:

```json
{
"expo": {
"plugins": [
[
"@clerk/expo",
{
"faceIDPermission": "Allow $(PRODUCT_NAME) to use Face ID for secure sign-in."
}
]
]
}
}
```

The plugin only adds the permission when `faceIDPermission` is provided and does not overwrite `ios.infoPlist.NSFaceIDUsageDescription` if your app already defines it.

You can also configure the key directly:

```json
{
"expo": {
"ios": {
"infoPlist": {
"NSFaceIDUsageDescription": "Allow $(PRODUCT_NAME) to use Face ID for secure sign-in."
}
}
}
}
```

## Support

For help, visit our [support page](https://clerk.com/contact/support?utm_source=github&utm_medium=clerk_expo).
Expand Down
6 changes: 4 additions & 2 deletions packages/expo/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def clerkExpoVersion = clerkExpoPackageJson.version.toString()
// See: https://docs.gradle.org/current/userguide/version_catalogs.html for app-level version catalogs
ext {
kotlinxCoroutinesVersion = "1.7.3"
clerkAndroidApiVersion = "1.0.36"
clerkAndroidUiVersion = "1.0.36"
clerkAndroidApiVersion = "1.0.37"
clerkAndroidUiVersion = "1.0.37"
Comment on lines +23 to +24

@coderabbitai coderabbitai Bot Jul 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Are com.clerk:clerk-android-api:1.0.37andcom.clerk:clerk-android-ui:1.0.37 released and publicly available from the Maven repository used by Clerk Expo consumers?

💡 Result:

As of July 27, 2026, the artifacts com.clerk:clerk-android-api:1.0.37 and com.clerk:clerk-android-ui:1.0.37 are not released and publicly available in Maven Central. The official Clerk Android SDK, which is published to Maven Central under the com.clerk group, currently has a latest released version of 1.0.33, published on July 8, 2026 [1][2]. There is no record of a 1.0.37 release for these specific artifacts in the official Maven repository used by Clerk consumers [3][4][1]. Clerk recommends checking their official GitHub releases page [1] or Maven Central directly to confirm the availability of specific versions [5][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== build.gradle snippet ==\n'
sed -n '1,80p' packages/expo/android/build.gradle

printf '\n== search for 1.0.37 references ==\n'
rg -n '1\.0\.37|clerk-android-(api|ui)' packages/expo -S || true

printf '\n== repository declarations ==\n'
rg -n 'mavenCentral|google\(\)|maven \{' packages/expo/android -S || true

Repository: clerk/javascript

Length of output: 1908


🏁 Script executed (no clone):

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json, urllib.request, urllib.error

urls = {
    "maven_api_1_0_37": "https://repo1.maven.org/maven2/com/clerk/clerk-android-api/1.0.37/",
    "maven_ui_1_0_37": "https://repo1.maven.org/maven2/com/clerk/clerk-android-ui/1.0.37/",
}
for name, url in urls.items():
    try:
        with urllib.request.urlopen(url, timeout=20) as r:
            print(name, r.status, r.geturl())
            print(r.read(200).decode("utf-8", "ignore"))
    except Exception as e:
        print(name, "ERROR", repr(e))
PY

Length of output: 327


Replace the Android SDK pins before merging. com.clerk:clerk-android-api:1.0.37 and com.clerk:clerk-android-ui:1.0.37 aren’t published yet, so @clerk/expo will fail to resolve Android dependencies for consumers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/expo/android/build.gradle` around lines 23 - 24, Update the
clerkAndroidApiVersion and clerkAndroidUiVersion pins to published Clerk Android
SDK versions before merging, ensuring both dependency coordinates resolve
successfully for `@clerk/expo` consumers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This PR is intentionally a draft and is blocked on the native SDK releases. These are temporary placeholder pins for the upcoming Android trusted-device release, so the Android CI failures are currently expected. Once Clerk Android is published, its release workflow will automatically open an Expo dependency-bump PR. I’ll rebase that change and use the published version before marking this PR ready or merging it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seanperez29, thanks for clarifying. That release-gating plan addresses the concern: keeping the placeholder pins is reasonable while this remains a draft, provided they are replaced by the published dependency-bump before the PR is marked ready or merged. I’ll leave the finding open until then.


✏️ Learnings added
Learnt from: seanperez29
Repo: clerk/javascript PR: 9257
File: packages/expo/android/build.gradle:23-24
Timestamp: 2026-07-27T19:04:52.833Z
Learning: For GitHub pull request `#9257` in `clerk/javascript`, `packages/expo/android/build.gradle` intentionally uses temporary unreleased Clerk Android SDK pins for trusted-device support while the PR remains a draft. Android CI failures are expected until Clerk Android publishes the release; its release workflow will open an Expo dependency-bump PR, which must be rebased and applied before this PR is marked ready or merged.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

composeVersion = "1.7.0"
activityComposeVersion = "1.9.0"
lifecycleVersion = "2.8.0"
Expand Down Expand Up @@ -132,4 +132,6 @@ dependencies {
implementation "androidx.activity:activity-compose:$activityComposeVersion"
implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleVersion"

testImplementation "junit:junit:4.13.2"
}
Loading
Loading