You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make react-dom an optional peer dependency in @clerk/expo so native Expo apps that do not use React DOM are not blocked by npm peer resolution while installing Clerk.
Why this is scoped to @clerk/expo
The direct install target for Expo apps is @clerk/expo, so this PR starts by marking react-dom optional on the Expo package itself. This mirrors the shape of Expo packages that expose both native and web entrypoints but should not require React DOM for native-only usage.
@clerk/expo also depends on @clerk/react, which still declares a react-dom peer. I tested the narrower Expo-only change first as requested. With only @clerk/expo patched, npm no longer fails the install with --legacy-peer-deps omitted, but npm still resolves react-dom@19.2.7 through the remaining transitive peer chain and npm ls reports an invalid tree against the app's react@19.2.3.
Root cause
Some native Expo apps do not install react-dom. When installing the current PR build of @clerk/expo into an Expo SDK 56 app with react@19.2.3 and no react-dom, npm selects the latest compatible react-dom, currently react-dom@19.2.7. That package requires react@^19.2.7, which conflicts with the app's react@19.2.3 and causes npm to fail unless --legacy-peer-deps is used.
The default SDK 56 template already includes react-dom@19.2.3, so it does not reproduce this particular resolver failure.
Summary by CodeRabbit
Chores
Updated @clerk/expo and @clerk/react with patch version bumps
Configured react-dom as an optional peer dependency to prevent unnecessary packages from being installed in native Expo applications
This PR marks react-dom as an optional peer dependency in the @clerk/expo and @clerk/react packages to prevent unnecessary installation in native Expo environments. The changeset documents patch version bumps, and packages/expo/package.json adds react-dom metadata marked as optional.
Changeset declares patch updates for @clerk/expo and @clerk/react with a note documenting that react-dom is an optional peer dependency. Package metadata in peerDependenciesMeta adds react-dom marked as optional: true.
Estimated code review effort
🎯 1 (Trivial) | ⏱️ ~5 minutes
Poem
A rabbit hops through deps so fine,
React-dom now optional, by design! 🐰
Expo apps stay light and lean,
Cleanest peer dep ever seen! ✨
The title 'fix(expo): make react-dom optional for native apps' accurately and concisely summarizes the main change: making react-dom optional in Expo packages to resolve peer dependency issues in native apps.
Docstring Coverage
✅ Passed
No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check
✅ Passed
Check skipped - CodeRabbit’s high-level summary is enabled.
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches📝 Generate docstrings
Create stacked PR
Commit on current branch
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Generated by Break Check on 2026-06-09T20:27:00.643Z
Summary
Metric
Count
Packages analyzed
19
Packages with changes
2
🔴 Breaking changes
6
🟡 Non-breaking changes
0
🟢 Additions
0
Warning
6 breaking change(s) detected - Major version bump required
🤖 This report was reviewed by claude-sonnet-4-6.
Note
Break Check could not snapshot 3 subpaths; the diff below excludes them.
@clerk/astro ./env: Internal Error: Unable to determine module for: /home/runner/_work/javascript/javascript/packages/astro/env.d.ts You have encountered a software defect. Please consider reporting the issue to the maintainers of this application.
@clerk/shared ./cookie: Internal Error: Unable to follow symbol for "Cookies" You have encountered a software defect. Please consider reporting the issue to the maintainers of this application.
@clerk/testing ./cypress: Symbol not found for identifier: Cypress
🔴 Breaking changes index (6)
Every breaking change, up front. Full diffs are in the package sections below.
Package
Subpath
Change
@clerk/astro
./client
$authStore
@clerk/astro
./client
$organizationStore
@clerk/astro
./client
$userStore
@clerk/shared
./react
UseOrganizationEnterpriseConnectionTestRunsParams
@clerk/shared
./react
UseOrganizationEnterpriseConnectionTestRunsReturn
@clerk/shared
./types
CreateOrganizationEnterpriseConnectionParams
@clerk/astro
Current version: 3.3.3 Recommended bump: MAJOR → 4.0.0
Static analyzer: Breaking change in variable $authStore: Type changed: $authStore:import("nanostores").ReadableAtom<{userId:string|null|undefined;user:!_clerk_shared__chunks_index_U8nAlSHe.h… → $authStore:import("nanostores").ReadableAtom<{userId:string|null|undefined;user:!_clerk_shared__chunks_index_BTxz__kZ.h…
🤖 AI review (confirmed) (95%): The referenced chunk module _clerk_shared__chunks_index_U8nAlSHe has been replaced with _clerk_shared__chunks_index_BTxz__kZ, a content-hashed internal bundle chunk. Per rule 12, these are non-resolvable specifiers and structural equivalence cannot excuse the change; consumer code referencing the old chunk path will fail to compile.
Migration: Upgrade any direct references to the internal _clerk_shared__chunks_index_U8nAlSHe chunk to use the new chunk or, preferably, reference only the public entry-point types exposed by @clerk/astro.
Static analyzer: Breaking change in variable $organizationStore: Type changed: $organizationStore:import("nanostores").ReadableAtom<!_clerk_shared__chunks_index_U8nAlSHe.Co:type|null|undefined> → $organizationStore:import("nanostores").ReadableAtom<!_clerk_shared__chunks_index_BTxz__kZ.Co:type|null|undefined>
🤖 AI review (confirmed) (95%): The type parameter of $organizationStore now references _clerk_shared__chunks_index_BTxz__kZ.Co instead of _clerk_shared__chunks_index_U8nAlSHe.Co; both chunk specifiers contain a content-hashed segment that is non-resolvable by consumers (rule 12), making this a breaking import path change.
Migration: Avoid importing types directly from internal _chunks paths; rely solely on the public @clerk/astro entry-point types for Organization.
Static analyzer: Breaking change in variable $userStore: Type changed: $userStore:import("nanostores").ReadableAtom<!_clerk_shared__chunks_index_U8nAlSHe.hs:type|null|undefined> → $userStore:import("nanostores").ReadableAtom<!_clerk_shared__chunks_index_BTxz__kZ.hs:type|null|undefined>
🤖 AI review (confirmed) (95%): The type parameter of $userStore now references _clerk_shared__chunks_index_BTxz__kZ.hs instead of _clerk_shared__chunks_index_U8nAlSHe.hs; the old chunk specifier is a non-resolvable content-hashed internal path (rule 12), breaking consumers who previously resolved the User type from it.
Migration: Avoid importing types directly from internal _chunks paths; rely solely on the public @clerk/astro entry-point types for User.
@clerk/shared
Current version: 4.15.0 Recommended bump: MAJOR → 5.0.0
Static analyzer: Breaking change in type alias UseOrganizationEnterpriseConnectionTestRunsParams: Type changed: {enterpriseConnectionId:string|null;params?:import("@clerk/shared").~GetEnterpriseConnectionTestRunsParams;pollInterval… → {enterpriseConnectionId:string|null;params?:import("@clerk/shared").~GetEnterpriseConnectionTestRunsParams;pollInterval…
🤖 AI review (confirmed) (95%): The keepPreviousData optional property was removed from UseOrganizationEnterpriseConnectionTestRunsParams; consumers who passed { keepPreviousData: true } will get a type error since the property no longer exists on the type.
Migration: Remove keepPreviousData from any object passed as UseOrganizationEnterpriseConnectionTestRunsParams; the property is no longer accepted.
Static analyzer: Breaking change in type alias UseOrganizationEnterpriseConnectionTestRunsReturn: Type changed: {data:import("@clerk/shared").~EnterpriseConnectionTestRunResource[]|undefined;totalCount:number|undefined;error:!Error… → {data:import("@clerk/shared").~EnterpriseConnectionTestRunResource[]|undefined;totalCount:number|undefined;error:!Error…
🤖 AI review (confirmed) (97%): The revalidate method's parameter options?: RevalidateTestRunsOptions was removed, so callers who invoke revalidate(options) with an argument will get a type error since the function no longer accepts any parameters.
Migration: Update all call sites that pass an argument to revalidate(...) to call it without arguments: revalidate().
Static analyzer: Breaking change in type alias CreateOrganizationEnterpriseConnectionParams: Type changed: {provider:import("@clerk/shared").OrganizationEnterpriseConnectionProvider;name:string;domains?:string[];organizationId… → {provider:import("@clerk/shared").OrganizationEnterpriseConnectionProvider;name:string;organizationId?:string|null;saml…
🤖 AI review (confirmed) (95%): The optional domains?: string[] property was removed from CreateOrganizationEnterpriseConnectionParams, which is used as an input parameter to createEnterpriseConnection and CreateMeEnterpriseConnectionParams; consumers who passed domains in that object will have their code break at compile time.
Migration: Remove the domains property from any objects passed to createEnterpriseConnection or CreateMeEnterpriseConnectionParams.
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
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
Make
react-doman optional peer dependency in@clerk/exposo native Expo apps that do not use React DOM are not blocked by npm peer resolution while installing Clerk.Why this is scoped to
@clerk/expoThe direct install target for Expo apps is
@clerk/expo, so this PR starts by markingreact-domoptional on the Expo package itself. This mirrors the shape of Expo packages that expose both native and web entrypoints but should not require React DOM for native-only usage.@clerk/expoalso depends on@clerk/react, which still declares areact-dompeer. I tested the narrower Expo-only change first as requested. With only@clerk/expopatched, npm no longer fails the install with--legacy-peer-depsomitted, but npm still resolvesreact-dom@19.2.7through the remaining transitive peer chain andnpm lsreports an invalid tree against the app'sreact@19.2.3.Root cause
Some native Expo apps do not install
react-dom. When installing the current PR build of@clerk/expointo an Expo SDK 56 app withreact@19.2.3and noreact-dom, npm selects the latest compatiblereact-dom, currentlyreact-dom@19.2.7. That package requiresreact@^19.2.7, which conflicts with the app'sreact@19.2.3and causes npm to fail unless--legacy-peer-depsis used.The default SDK 56 template already includes
react-dom@19.2.3, so it does not reproduce this particular resolver failure.Summary by CodeRabbit
@clerk/expoand@clerk/reactwith patch version bumps