fix(expo): align native prebuilt component APIs#8699
Draft
mikepitre wants to merge 14 commits into
Draft
Conversation
🦋 Changeset detectedLatest commit: 91dbd71 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/hono
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/react
@clerk/react-router
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/ui
@clerk/upgrade
@clerk/vue
commit: |
swolfand
reviewed
May 28, 2026
swolfand
reviewed
May 28, 2026
seanperez29
reviewed
Jun 1, 2026
swolfand
approved these changes
Jun 1, 2026
seanperez29
approved these changes
Jun 1, 2026
ddb711a to
cbe462f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR aligns the Expo native prebuilt component surface with the way the Clerk iOS and Android SDKs are used directly: native views render content, app code owns presentation, and auth state is observed through the provider/hooks instead of component-specific completion callbacks.
Important pieces
Make
AuthViewandUserProfileViewapp-presented contentpresentAuth/presentUserProfilehelper paths, Android presentation activities, the user-profile modal hook, and the stale inline component aliases.clerk-iospatterns like presentingAuthView()in a sheet. The prebuilt view should not decide whether it is full screen, sheet, route, or inline content.Wrap the platform-native
UserButtonUserButtonview managers on iOS and Android and removes the JS avatar/button implementation.UserButtonshould behave like the native SDK button, including presenting the native user profile itself. JS should not reimplement the avatar, tap behavior, or profile presentation.Centralize native-to-JS auth state sync in
ClerkProviderAuthViewandUserProfileView.useAuth()already owns auth state for app developers. Component-level callbacks likeonCompleteduplicate that responsibility and make examples clunkier.Keep JS sign-out and native sign-out in sync
NativeSessionSyncnow avoids clearing a persisted native session during cold start before JS has adopted it, while still propagating a real JS sign-out to native.AuthViewsign-in, nativeUserButtonsign-out, and JSsignOut()should all converge on one session state.Trim bridge surface area
Before / after examples
Auth presentation
Before: Expo exposed imperative native presentation helpers, so presentation was owned by the SDK bridge.
After:
AuthViewis content. The app chooses sheet, route, full screen, or inline presentation.Full-screen/root auth
Before: full-screen behavior came from native presentation-specific bridge code.
After: render
AuthViewwherever the app wants it to live.User button
Before:
UserButtonreimplemented avatar rendering in JS, fetched native user state, and manually called the native profile presenter.After:
UserButtonis backed by the platform-native Clerk button. Tapping it opens the native user profile, just like the iOS and Android SDKs.User profile presentation
Before: profile presentation could be driven through Expo-specific imperative helpers.
After:
UserProfileViewis content. The app owns the presentation surface.Auth completion
Before:
AuthViewparsed native completion events and synced JS state from inside the component.After: auth completion is observed through Clerk auth state. The component stays presentation/content-only.
Testing
pnpm --filter @clerk/expo format:checkpnpm --filter @clerk/expo test@clerk/react/internalresolver issue when lintingClerkProvider.tsx.clerk-expo-quickstart:npx tsc --noEmitclerk-expo-quickstart:npx expo run:ios --device 9A1571DF-CC3D-465F-A2E1-C89EC2388B31Notes
UserButtonkeeps a tiny36x36host style because React Native/Yoga does not infer the intrinsic size of the native host view. The native SDK still owns rendering and presentation.minor, notmajor, because these prebuilt components are still beta and this is expected beta-surface iteration rather than a stable package-level breaking release.