Skip to content

Conversation

@chriscanin
Copy link
Contributor

@chriscanin chriscanin commented Nov 6, 2025

Description

This update was made to resolve a module loading issue with users who are not using the optional Sign In With Apple hook.

In useSignInWithApple.ios.ts we had:
import * as AppleAuthentication from 'expo-apple-authentication';

This does not work because when xcode, or eas (fastlane) go to bundle the application, we expect expo-apple-authentication to be available. To make these modules optional, we now dynamically import expo-apple-authentication only when needed.

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:

Summary by CodeRabbit

  • Bug Fixes
    • Prevented module resolution errors for users who don't use Sign in with Apple by deferring loading of its dependencies until the feature is invoked.
    • When the feature is invoked but required packages are missing, a clear runtime error is returned so the issue can be addressed.

@changeset-bot
Copy link

changeset-bot bot commented Nov 6, 2025

🦋 Changeset detected

Latest commit: d2a2314

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

This PR includes changesets to release 1 package
Name Type
@clerk/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
Copy link

vercel bot commented Nov 6, 2025

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

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Nov 6, 2025 6:52pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 6, 2025

Walkthrough

Converts static imports of expo-apple-authentication and expo-crypto in the useSignInWithApple hook to runtime (dynamic) imports; adds try/catch to surface a clear error if those modules are not installed when the hook is invoked.

Changes

Cohort / File(s) Summary
Changeset documentation
.changeset/fix-expo-apple-auth-optional.md
Adds a patch changeset documenting the fix for @clerk/clerk-expo, noting that expo-apple-authentication and expo-crypto are now loaded dynamically.
Hook implementation
packages/expo/src/hooks/useSignInWithApple.ios.ts
Replaces top-level/static imports of expo-apple-authentication and expo-crypto with dynamic imports inside the hook. Adds a try/catch around the runtime imports and returns an error via the hook's error path if imports fail; subsequent availability check and sign-in flow use the dynamically loaded modules.

Sequence Diagram(s)

sequenceDiagram
    participant App as App / Consumer
    participant Hook as useSignInWithApple
    participant Modules as Runtime Modules

    Note over Hook,Modules: New behavior — imports deferred until hook call
    App->>Hook: invoke signInWithApple()
    Hook->>Modules: dynamic import('expo-apple-authentication')\nand import('expo-crypto')
    alt import succeeds
        Hook->>Modules: AppleAuthentication.isAvailableAsync()
        alt available
            Hook->>Modules: perform cryptographic steps (Crypto)
            Hook->>App: return credential / success
        else not available
            Hook->>App: return availability error
        end
    else import fails
        Hook->>App: throw/return error indicating modules must be installed
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Focus areas for review:
    • Ensure the try/catch surfaces an actionable error message and integrates with the hook's error handling.
    • Verify no remaining top-level references to the now-dynamic modules.
    • Confirm TypeScript typings or any lint rules handle dynamic imports as used.

Poem

🐰 I waited in the burrow, quiet and small,
Until you called my hook to fetch the ball.
Now Apple and Crypto only wake when you plea,
Light-footed imports — hop in, run free! 🍎✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: converting static imports to dynamic imports to resolve module loading issues for the optional Sign in with Apple feature.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chris/mobile-306-expo-error-on-bundling-2182

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.

❤️ Share

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

@chriscanin chriscanin requested a review from dstaley November 6, 2025 18:17
@chriscanin chriscanin self-assigned this Nov 6, 2025
@chriscanin chriscanin added the expo label Nov 6, 2025
@chriscanin chriscanin marked this pull request as ready for review November 6, 2025 18:18
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/expo/src/hooks/useSignInWithApple.ios.ts (1)

76-81: Consider logging the import error for debugging.

The caught error parameter is unused. While the error message is clear and actionable, logging the underlying error could help diagnose module loading failures (e.g., version mismatches, installation issues).

 } catch (error) {
+  console.error('Failed to load Apple authentication modules:', error);
   return errorThrower.throw(
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4fc9240 and 11947c6.

📒 Files selected for processing (3)
  • .changeset/fix-expo-apple-auth-optional.md (1 hunks)
  • packages/expo/package.json (1 hunks)
  • packages/expo/src/hooks/useSignInWithApple.ios.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
.changeset/**

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Automated releases must use Changesets.

Files:

  • .changeset/fix-expo-apple-auth-optional.md
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
  • packages/expo/package.json
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
packages/*/package.json

📄 CodeRabbit inference engine (.cursor/rules/global.mdc)

All publishable packages should be placed under the packages/ directory

packages/*/package.json: All publishable packages must be located in the 'packages/' directory.
All packages must be published under the @clerk namespace on npm.
Semantic versioning must be used across all packages.

Files:

  • packages/expo/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
packages/expo/package.json (1)

3-3: LGTM! Appropriate patch version bump.

The patch-level version increment is appropriate for this bug fix that makes optional dependencies truly optional at bundle time.

.changeset/fix-expo-apple-auth-optional.md (1)

1-5: LGTM! Changeset accurately describes the fix.

The changeset correctly documents the patch-level change and provides a clear explanation of the problem and solution.

packages/expo/src/hooks/useSignInWithApple.ios.ts (1)

83-154: LGTM! Dynamic import approach successfully resolves the bundling issue.

The implementation correctly defers module loading until the hook is actually invoked, making expo-apple-authentication and expo-crypto truly optional at bundle time. The existing authentication flow logic remains sound, and the dynamically imported modules are used correctly throughout.

Comment on lines 70 to 82
// Dynamically import expo-apple-authentication only when needed
let AppleAuthentication;
let Crypto;

try {
[AppleAuthentication, Crypto] = await Promise.all([import('expo-apple-authentication'), import('expo-crypto')]);
} catch (error) {
return errorThrower.throw(
'expo-apple-authentication is required to use Sign in with Apple. ' +
'Please install it by running: npx expo install expo-apple-authentication expo-crypto',
);
}

Copy link
Contributor

@coderabbitai coderabbitai bot Nov 6, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add explicit type annotations for dynamically imported modules.

The variables AppleAuthentication and Crypto lack explicit type annotations, which violates the TypeScript coding guidelines. Dynamic imports return module namespace objects that have specific types.

Apply this diff to add explicit type annotations:

 // Dynamically import expo-apple-authentication only when needed
-let AppleAuthentication;
-let Crypto;
+let AppleAuthentication: typeof import('expo-apple-authentication');
+let Crypto: typeof import('expo-crypto');

 try {
   [AppleAuthentication, Crypto] = await Promise.all([import('expo-apple-authentication'), import('expo-crypto')]);

As per coding guidelines: "Always define explicit return types for functions, especially public APIs" and "Avoid any type - prefer unknown when type is uncertain, then narrow with type guards."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Dynamically import expo-apple-authentication only when needed
let AppleAuthentication;
let Crypto;
try {
[AppleAuthentication, Crypto] = await Promise.all([import('expo-apple-authentication'), import('expo-crypto')]);
} catch (error) {
return errorThrower.throw(
'expo-apple-authentication is required to use Sign in with Apple. ' +
'Please install it by running: npx expo install expo-apple-authentication expo-crypto',
);
}
// Dynamically import expo-apple-authentication only when needed
let AppleAuthentication: typeof import('expo-apple-authentication');
let Crypto: typeof import('expo-crypto');
try {
[AppleAuthentication, Crypto] = await Promise.all([import('expo-apple-authentication'), import('expo-crypto')]);
} catch (error) {
return errorThrower.throw(
'expo-apple-authentication is required to use Sign in with Apple. ' +
'Please install it by running: npx expo install expo-apple-authentication expo-crypto',
);
}
🤖 Prompt for AI Agents
In packages/expo/src/hooks/useSignInWithApple.ios.ts around lines 70 to 82, the
dynamically imported variables AppleAuthentication and Crypto lack explicit
TypeScript annotations; add explicit types such as declaring
AppleAuthentication: typeof import('expo-apple-authentication') | unknown and
Crypto: typeof import('expo-crypto') | unknown (or use unknown first and then
narrow/cast with type guards) to avoid implicit any, then narrow before use (or
import the module types and annotate directly) so the code follows the guideline
of explicit types and avoids any.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Coderrabbit, trix are for kids... These type annotations are not allowed in our codebase according to the linting rules:
import() type annotations are forbidden.eslint@typescript-eslint/consistent-type-imports

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🌐 Web query:

@typescript-eslint/consistent-type-imports dynamic import typing patterns

💡 Result:

Short summary + patterns and how the rule affects them:

  1. Rule basics
  • @typescript-eslint/consistent-type-imports enforces using type-only imports (or not) and has options prefer, fixStyle (inline-type-imports | separate-type-imports) and disallowTypeAnnotations. [1]
  1. Preferred patterns for dynamic imports (typing runtime import() results)
  • Value import (runtime): use const mod = await import('./x'); then use mod.foo (no type-only import involved).
  • Type for module shape (recommended, separate-style):
    • import type { Foo } from './x'; type T = Foo; — works with the rule when prefer: 'type-imports' + fixStyle:'separate-type-imports'. [1]
  • Inline type imports (TypeScript ≥4.5) — single import can mix values and type names:
    • import { func, type TypeName } from './x'; — controlled by fixStyle:'inline-type-imports'. [1][3]
  • Typing the dynamic import expression (type-only import() vs typeof import()):
    • type OnlyFromImportType = import('./x').Foo; // this is an inline type import (import() in a type position)
    • type ModuleType = typeof import('./x'); // gets the runtime module type (useful for describing default/exports)
      Note: consistent-type-imports has option disallowTypeAnnotations which, when true, forbids type positions using import(...) syntax — so import('./x').T may be flagged. If you want to allow import() types, set disallowTypeAnnotations: false. [2]
  1. Practical patterns depending on rule config
  • If prefer: 'type-imports' + disallowTypeAnnotations: true (default):
    • Use import type { T } from './x' or inline type modifiers (import { type T } ...) rather than type import('./x').T. [1][2]
  • If you need the module's runtime type (e.g., to type a wrapper around dynamic import):
    • Use type Mod = typeof import('./x'); const m = await import('./x') as Promise; or cast the awaited result: const m = (await import('./x')) as unknown as Mod.
    • Or keep value-level import and derive types with import type { Foo } from './x' and use Foo for typing values returned (if exports are types/values).
  1. Recommendations
  • Prefer import type / import { type X } for named types (obeying fixStyle choice).
  • If you must use import('./x').T, set disallowTypeAnnotations: false in the rule (but be aware many projects prefer explicit import type forms). [1][2]
  • For typing dynamic import results, favor typeof import('./x') when you need the module shape at the type level; otherwise import type { T } is clearer.

Sources
[1] @typescript-eslint/consistent-type-imports docs.
[2] Rule details / options (node docs and rule README).
[3] TypeScript import { type ... } syntax discussion (Stack Overflow).


@chriscanin, you're absolutely right—my apologies for the incorrect suggestion!

Given your ESLint rule configuration with disallowTypeAnnotations: true, the typeof import() syntax is indeed forbidden. With dynamic imports designed to make the module optional at bundle time, you're facing a tradeoff between type safety and the primary goal.

Your current approach (implicit any for the dynamically imported variables) is actually pragmatic here. The alternatives would be:

  1. Use unknown and type assertions - More verbose but maintains some type safety:

    let AppleAuthentication: unknown;
    let Crypto: unknown;
    
    // Later, use with type assertions
    const isAvailable = await (AppleAuthentication as any).isAvailableAsync();
  2. Accept the implicit any - Simpler and acceptable given:

    • The modules are used immediately after import
    • The try-catch provides runtime safety
    • Type errors would surface quickly during development
    • The primary goal (optional bundling) is preserved

Given the constraints, I'd recommend keeping your current implementation as-is. The implicit any is a reasonable tradeoff when the linting rules prevent proper typing of dynamic imports.

@chriscanin chriscanin changed the title fix(expo): Resolve module loading issue for optional Sign in with Apple fix(clerk-expo): Resolve module loading issue for optional Sign in with Apple Nov 6, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 6, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7171

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7171

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@7171

@clerk/clerk-expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/clerk-react

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

@clerk/react-router

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

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@7171

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@7171

@clerk/types

npm i https://pkg.pr.new/@clerk/types@7171

@clerk/upgrade

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

@clerk/vue

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

commit: d2a2314

Co-authored-by: Dylan Staley <88163+dstaley@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/expo/src/hooks/useSignInWithApple.ios.ts (1)

70-82: Solid dynamic import implementation for optional dependencies.

The dynamic import approach effectively resolves the bundling issue by loading expo-apple-authentication and expo-crypto only at runtime when the hook is invoked. Using Promise.all for parallel imports is good for performance, and the error handling provides clear guidance to developers.

The implicit any types are an acceptable tradeoff given your linting constraints (as discussed in the previous review).


Optional improvement: Clarify that both packages are required.

The error message could be slightly more explicit about both dependencies being required:

     return errorThrower.throw(
-        'expo-apple-authentication is required to use Sign in with Apple. ' +
-          'Please install it by running: npx expo install expo-apple-authentication expo-crypto',
+        'expo-apple-authentication and expo-crypto are required to use Sign in with Apple. ' +
+          'Please install them by running: npx expo install expo-apple-authentication expo-crypto',
     );
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7cc7ef6 and d2a2314.

📒 Files selected for processing (1)
  • packages/expo/src/hooks/useSignInWithApple.ios.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/expo/src/hooks/useSignInWithApple.ios.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Build Packages
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (3)
packages/expo/src/hooks/useSignInWithApple.ios.ts (3)

17-68: LGTM: Excellent documentation and setup.

The JSDoc comments are comprehensive and provide a clear usage example. The function signature and initial setup (loading checks) are clean and well-structured.


84-139: LGTM: Authentication flow correctly handles all scenarios.

The implementation properly:

  • Checks device availability before attempting authentication
  • Generates a cryptographically secure nonce using Crypto.randomUUID()
  • Requests appropriate scopes (FULL_NAME, EMAIL)
  • Validates the identity token
  • Handles the transfer flow for new users with optional metadata
  • Returns the correct session for existing users

The dynamic imports integrate seamlessly into the authentication flow.


140-154: LGTM: Robust error handling for user cancellations and errors.

The error handling correctly distinguishes between:

  • User-initiated cancellations (ERR_REQUEST_CANCELED) → graceful return with null session
  • Actual errors → re-thrown for upstream handling

The type guard pattern for checking the error shape is defensive and appropriate.

@chriscanin chriscanin merged commit 35c831b into main Nov 6, 2025
70 of 71 checks passed
@chriscanin chriscanin deleted the chris/mobile-306-expo-error-on-bundling-2182 branch November 6, 2025 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants