Skip to content

fix(expo): Allow disabling native client sync - #9396

Merged
wobsoriano merged 5 commits into
mainfrom
rob/internal-disable-native-client-sync
Aug 11, 2026
Merged

fix(expo): Allow disabling native client sync#9396
wobsoriano merged 5 commits into
mainfrom
rob/internal-disable-native-client-sync

Conversation

@wobsoriano

@wobsoriano wobsoriano commented Aug 11, 2026

Copy link
Copy Markdown
Member

Description

Adds an experimental ClerkProvider prop to disable native client synchronization for Expo apps that do not use Clerk native components. This provides a temporary escape hatch for apps affected by native and JS client desynchronization.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1ae7c7c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/expo Patch

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

@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview Aug 11, 2026 4:02pm
swingset Ready Ready Preview Aug 11, 2026 4:02pm

Request Review

@pkg-pr-new

pkg-pr-new Bot commented Aug 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9396

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9396

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9396

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9396

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9396

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9396

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9396

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9396

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9396

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9396

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9396

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9396

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9396

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9396

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9396

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9396

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9396

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9396

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9396

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9396

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9396

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9396

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9396

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9396

commit: 1ae7c7c

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-11T16:06:59.059Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 1
🔴 Breaking changes 0
🟡 Non-breaking changes 2
🟢 Additions 0

🤖 This report was reviewed by claude-sonnet-4-6.


@clerk/expo

Current version: 4.2.5
Recommended bump: MINOR → 4.3.0

Subpath .

🟡 Non-breaking Changes (1)

Modified: ClerkProviderProps
// ... 2 unchanged lines elided ...
      tokenCache?: TokenCache;
      __experimental_passkeys?: BuildClerkOptions['__experimental_passkeys'];
      __experimental_resourceCache?: BuildClerkOptions['__experimental_resourceCache'];
+     __experimental_disableNativeClientSync?: boolean;
  };

Static analyzer: Breaking change in type alias ClerkProviderProps: Type changed: !Omit:type<import("@clerk/react").ClerkProviderProps<TUi>,'publishableKey'>&{publishableKey:string;tokenCache?:import("…!Omit:type<import("@clerk/react").ClerkProviderProps<TUi>,'publishableKey'>&{publishableKey:string;tokenCache?:import("…

🤖 AI review (reclassified as non-breaking) (97%): The only change is the addition of a new optional property __experimental_disableNativeClientSync?: boolean to ClerkProviderProps, which is an input type (used as a parameter to ClerkProvider). Adding an optional property to an input type does not break existing consumers who omit it.

Subpath ./types

🟡 Non-breaking Changes (1)

Modified: ClerkProviderProps
// ... 2 unchanged lines elided ...
      tokenCache?: TokenCache;
      __experimental_passkeys?: BuildClerkOptions['__experimental_passkeys'];
      __experimental_resourceCache?: BuildClerkOptions['__experimental_resourceCache'];
+     __experimental_disableNativeClientSync?: boolean;
  };

Static analyzer: Breaking change in type alias ClerkProviderProps: Type changed: !Omit:type<import("@clerk/react").ClerkProviderProps<TUi>,'publishableKey'>&{publishableKey:string;tokenCache?:import("…!Omit:type<import("@clerk/react").ClerkProviderProps<TUi>,'publishableKey'>&{publishableKey:string;tokenCache?:import("…

🤖 AI review (reclassified as non-breaking) (95%): A new optional property __experimental_disableNativeClientSync?: boolean is added to ClerkProviderProps, which is an input type (passed as props to ClerkProvider); adding an optional field to an input type does not break existing callers who do not supply it.


Report generated by Break Check

Last ran on 1ae7c7c.

@wobsoriano
wobsoriano requested a review from swolfand August 11, 2026 14:48
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 97deaf8f-bd47-466a-8902-2cca67ee8d1a

📥 Commits

Reviewing files that changed from the base of the PR and between 2dbf5bf and 1ae7c7c.

📒 Files selected for processing (1)
  • integration/templates/expo-native/App.tsx
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)
  • clerk/cli (auto-detected)
  • clerk/clerk-ios (auto-detected)
  • clerk/clerk-android (auto-detected)

📝 Walkthrough

Walkthrough

Adds the experimental __experimental_disableNativeClientSync option to ClerkProvider. The option gates native bootstrap, event synchronization, and NativeClientSync rendering. The bootstrap hook responds to enabled-state changes. Tests cover disabled synchronization. The Expo native fixture removes JavaScript sign-in and E2E controls and updates profile rendering. A patch changeset documents the option.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: mikepitre

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: allowing Expo apps to disable native client synchronization.
Description check ✅ Passed The description explains the experimental prop, its intended use, and the related synchronization issue.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/expo/src/provider/nativeClientSync.tsx (1)

987-991: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Invalidate bootstrap work when enabled changes.

When enabled changes to false, the next effect sets isMountedRef.current back to true. An in-flight configureNativeClerk can then continue token-cache reads, native configuration, or synchronization while disabled. Clear the started key and readiness state when disabled, and use an effect-local cancellation token or generation counter. Include tests for both enable transitions.

🤖 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/src/provider/nativeClientSync.tsx` around lines 987 - 991,
Update the effect governing native bootstrap around configureNativeClerk so
disabling enabled invalidates in-flight work: clear startedPublishableKeyRef and
readiness state, and use an effect-local cancellation token or generation
counter checked before token-cache reads, native configuration, and
synchronization. Ensure re-enabling starts a fresh bootstrap for the
publishableKey, and add tests covering both enabled-to-disabled and
disabled-to-enabled transitions.
🧹 Nitpick comments (1)
packages/expo/src/provider/__tests__/ClerkProvider.nativeClientSync.test.tsx (1)

175-200: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for runtime opt-out transitions.

This test covers only the initially disabled provider. Add cases that disable synchronization during bootstrap and re-enable it after disabling. Assert that no native work continues while disabled and that a fresh bootstrap handles the later enable.

As per coding guidelines, “Unit tests are required for all new functionality. Include tests for all new features. Verify proper error handling and edge cases.”

🤖 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/src/provider/__tests__/ClerkProvider.nativeClientSync.test.tsx`
around lines 175 - 200, Extend the native client synchronization tests around
ClerkProvider to cover runtime opt-out transitions: disable synchronization
during bootstrap and verify no native configuration, token retrieval, listener
setup, or state syncing continues, then re-enable it and verify a fresh
bootstrap performs the expected native work. Reuse the existing mocks and
synchronization controls in the test suite, and preserve the current
initially-disabled assertions.

Source: Coding guidelines

🤖 Prompt for all review comments with 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.

Outside diff comments:
In `@packages/expo/src/provider/nativeClientSync.tsx`:
- Around line 987-991: Update the effect governing native bootstrap around
configureNativeClerk so disabling enabled invalidates in-flight work: clear
startedPublishableKeyRef and readiness state, and use an effect-local
cancellation token or generation counter checked before token-cache reads,
native configuration, and synchronization. Ensure re-enabling starts a fresh
bootstrap for the publishableKey, and add tests covering both
enabled-to-disabled and disabled-to-enabled transitions.

---

Nitpick comments:
In
`@packages/expo/src/provider/__tests__/ClerkProvider.nativeClientSync.test.tsx`:
- Around line 175-200: Extend the native client synchronization tests around
ClerkProvider to cover runtime opt-out transitions: disable synchronization
during bootstrap and verify no native configuration, token retrieval, listener
setup, or state syncing continues, then re-enable it and verify a fresh
bootstrap performs the expected native work. Reuse the existing mocks and
synchronization controls in the test suite, and preserve the current
initially-disabled assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: a94a3db7-7ced-4f48-9b1f-ef7d75ee28e5

📥 Commits

Reviewing files that changed from the base of the PR and between 29c9017 and f7ad951.

📒 Files selected for processing (4)
  • .changeset/calm-pandas-sync.md
  • packages/expo/src/provider/ClerkProvider.tsx
  • packages/expo/src/provider/__tests__/ClerkProvider.nativeClientSync.test.tsx
  • packages/expo/src/provider/nativeClientSync.tsx
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)
  • clerk/cli (auto-detected)
  • clerk/clerk-ios (auto-detected)
  • clerk/clerk-android (auto-detected)

@wobsoriano
wobsoriano merged commit a0124c5 into main Aug 11, 2026
58 checks passed
@wobsoriano
wobsoriano deleted the rob/internal-disable-native-client-sync branch August 11, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants