Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e996fdc
feat(expo): Move Google Sign to a new package
wobsoriano Jun 26, 2026
826baf2
chore: remove unused tests
wobsoriano Jun 26, 2026
0acf84e
exclude from pkg-pr-new snapshots
wobsoriano Jul 1, 2026
dc85481
exclude from pkg-pr-new snapshots
wobsoriano Jul 1, 2026
d6dd173
exclude from pkg-pr-new snapshots
wobsoriano Jul 1, 2026
f17c8e3
chore: update changeset
wobsoriano Jul 1, 2026
27a1678
chore: revert ci change
wobsoriano Jul 1, 2026
571197b
chore: dedupe
wobsoriano Jul 1, 2026
5a34117
ci: Add new package to break checn and native build workflow
wobsoriano Jul 3, 2026
5b5fa2f
chore: address coderabbit comments
wobsoriano Jul 4, 2026
e3909ec
Merge branch 'main' into rob/mobile-560
wobsoriano Jul 17, 2026
768a88d
Merge branch 'main' into rob/mobile-560
wobsoriano Jul 17, 2026
0554491
test(e2e): cover expo-google-signin build and hook wiring
wobsoriano Jul 17, 2026
1f0027f
chore(expo-google-signin): Bump peer dep
wobsoriano Jul 17, 2026
7739350
chore: update changeset
wobsoriano Jul 17, 2026
c9bf3b8
ci: add break check entries to api-changes
wobsoriano Jul 20, 2026
e7d27b4
chore: update changeset
wobsoriano Jul 20, 2026
36658f4
chore: update correct package info
wobsoriano Jul 20, 2026
9b40b5a
refactor(expo): Make expo-google-signin a native-only package
wobsoriano Jul 20, 2026
f550f7b
chore: update correct package info
wobsoriano Jul 20, 2026
a3a6b21
chore: Drop Expo SDK 53 support
wobsoriano Jul 21, 2026
81522a4
Merge branch 'main' into rob/mobile-560
wobsoriano Jul 21, 2026
2196ff5
chore: Bump react-native-url-polyfill to 4.0.0
wobsoriano Jul 21, 2026
9a408fc
chore: revert re-exported types
wobsoriano Jul 21, 2026
2dc5feb
Merge branch 'main' into rob/mobile-560
wobsoriano Jul 21, 2026
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
8 changes: 8 additions & 0 deletions .changeset/drop-expo-sdk-53.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@clerk/expo': major
'@clerk/expo-passkeys': major
---

Drop support for Expo SDK 53. The minimum supported version is now Expo SDK 54.

Expo maintains each SDK release for approximately one year and SDK 53 is now outside that window. Upgrade your app to Expo SDK 54 or later before updating these packages.
24 changes: 24 additions & 0 deletions .changeset/expo-google-signin-package.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@clerk/expo': major
'@clerk/expo-google-signin': major
---

The native Google Sign-In module has moved out of `@clerk/expo` into a new optional package, `@clerk/expo-google-signin`. Apps that don't use `useSignInWithGoogle` no longer pull in the native Google Sign-In dependencies during prebuild.

If you use native Google Sign-In, install the new package:

```sh
npx expo install @clerk/expo-google-signin
```

add its config plugin alongside `@clerk/expo` in your app config:

```json
{
"expo": {
"plugins": ["@clerk/expo", "@clerk/expo-google-signin"]
}
}
```

then rebuild your native app. The `useSignInWithGoogle` hook is still exported from `@clerk/expo/google` and its API is unchanged; it now requires `@clerk/expo-google-signin` to provide the native module, and throws an actionable error if it is missing.
2 changes: 2 additions & 0 deletions .github/workflows/api-changes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ on:
- 'packages/chrome-extension/**'
- 'packages/clerk-js/**'
- 'packages/expo/**'
- 'packages/expo-google-signin/**'
- 'packages/expo-passkeys/**'
- 'packages/express/**'
- 'packages/fastify/**'
Expand Down Expand Up @@ -54,6 +55,7 @@ env:
--filter=@clerk/chrome-extension
--filter=@clerk/clerk-js
--filter=@clerk/expo
--filter=@clerk/expo-google-signin
--filter=@clerk/expo-passkeys
--filter=@clerk/express
--filter=@clerk/fastify
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/expo-native-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- 'integration/templates/expo-native/**'
- 'integration/tests/expo-native/**'
- 'packages/expo/**'
- 'packages/expo-google-signin/**'
workflow_dispatch:

permissions:
Expand Down Expand Up @@ -74,11 +75,12 @@ jobs:
- name: Install monorepo dependencies
run: pnpm install --frozen-lockfile

- name: Build and pack @clerk/expo
- name: Build and pack Clerk packages
run: |
pnpm --filter @clerk/expo... build
mkdir -p "$SDK_PACK_DIR"
pnpm --filter @clerk/expo pack --pack-destination "$SDK_PACK_DIR"
pnpm --filter @clerk/expo-google-signin pack --pack-destination "$SDK_PACK_DIR"

- name: Install fixture dependencies
working-directory: ${{ env.FIXTURE_DIR }}
Expand All @@ -88,8 +90,10 @@ jobs:
run: |
cp "package.sdk-$EXPO_SDK.json" package.json
pnpm install --no-frozen-lockfile
SDK_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-*.tgz)"
pnpm add "$SDK_TARBALL" -w
# [0-9] keeps this glob off the clerk-expo-google-signin tarball.
SDK_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-[0-9]*.tgz)"
GOOGLE_SIGNIN_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-google-signin-*.tgz)"
pnpm add "$SDK_TARBALL" "$GOOGLE_SIGNIN_TARBALL" -w
# expo-dev-client makes even release builds boot into the dev
# launcher (unreachable Metro in CI), which stalls every Maestro
# flow on a blank screen. Skip it on e2e jobs only.
Expand Down
16 changes: 16 additions & 0 deletions integration/templates/expo-native/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ClerkProvider, useAuth, useUser } from '@clerk/expo';
import { useSignInWithGoogle } from '@clerk/expo/google';
import { AuthView, UserButton } from '@clerk/expo/native';
import { tokenCache } from '@clerk/expo/token-cache';
import { useState } from 'react';
Expand All @@ -13,7 +14,9 @@ if (!publishableKey) {
function NativeBuildFixture() {
const { isLoaded, isSignedIn, signOut } = useAuth({ treatPendingAsSignedOut: false });
const { user } = useUser();
const { startGoogleAuthenticationFlow } = useSignInWithGoogle();
const [isAuthOpen, setIsAuthOpen] = useState(false);
const [googleResult, setGoogleResult] = useState<string | null>(null);

return (
<View style={styles.container}>
Expand All @@ -29,6 +32,19 @@ function NativeBuildFixture() {
title='Open native AuthView'
onPress={() => setIsAuthOpen(true)}
/>
{!isSignedIn && (
<Button
testID='google-sign-in-button'
title='Sign in with Google'
onPress={() => {
void startGoogleAuthenticationFlow().catch((error: unknown) => {
const message = error instanceof Error ? error.message : String(error);
setGoogleResult(message.replace(/\s+/g, ' '));
});
}}
/>
)}
{googleResult && <Text testID='google-result'>{googleResult}</Text>}
{isSignedIn && (
<Button
testID='sign-out-button'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
appId: com.clerk.exponativebuildfixture
name: useSignInWithGoogle surfaces the missing-credentials error
---
- runFlow: subflows/open-app.yaml
- tapOn:
id: 'google-sign-in-button'
- extendedWaitUntil:
visible: '.*Google Sign-In credentials not found.*'
timeout: 15000
39 changes: 39 additions & 0 deletions packages/expo-google-signin/android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'maven-publish'

group = 'expo.modules.clerk.googlesignin'
version = '1.0.0'

def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
apply from: expoModulesCorePlugin
applyKotlinExpoModulesCorePlugin()
useCoreDependencies()
useExpoPublishing()

buildscript {
ext.safeExtGet = { prop, fallback ->
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
}

android {
namespace "expo.modules.clerk.googlesignin"

compileSdkVersion safeExtGet("compileSdkVersion", 36)

defaultConfig {
minSdkVersion safeExtGet("minSdkVersion", 24)
targetSdkVersion safeExtGet("targetSdkVersion", 36)
versionCode 1
versionName "1.0.0"
}
}

dependencies {
implementation project(':expo-modules-core')
implementation "androidx.credentials:credentials:1.3.0"
implementation "androidx.credentials:credentials-play-services-auth:1.3.0"
implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
5 changes: 5 additions & 0 deletions packages/expo-google-signin/app.plugin.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { ConfigPlugin } from '@expo/config-plugins';

declare const withClerkExpoGoogleSignIn: ConfigPlugin;

export = withClerkExpoGoogleSignIn;
32 changes: 32 additions & 0 deletions packages/expo-google-signin/app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const { withInfoPlist, createRunOncePlugin } = require('@expo/config-plugins');
const pkg = require('./package.json');

const withClerkExpoGoogleSignIn = config => {
const iosUrlScheme =
process.env.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME ||
(config.extra && config.extra.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME);

if (!iosUrlScheme) {
return config;
}

return withInfoPlist(config, modConfig => {
if (!Array.isArray(modConfig.modResults.CFBundleURLTypes)) {
modConfig.modResults.CFBundleURLTypes = [];
}

const schemeExists = modConfig.modResults.CFBundleURLTypes.some(urlType =>
urlType.CFBundleURLSchemes?.includes(iosUrlScheme),
);

if (!schemeExists) {
modConfig.modResults.CFBundleURLTypes.push({
CFBundleURLSchemes: [iosUrlScheme],
});
}

return modConfig;
});
};

module.exports = createRunOncePlugin(withClerkExpoGoogleSignIn, pkg.name, pkg.version);
9 changes: 9 additions & 0 deletions packages/expo-google-signin/expo-module.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"platforms": ["apple", "android"],
"apple": {
"modules": ["ClerkGoogleSignInModule"]
},
"android": {
"modules": ["expo.modules.clerk.googlesignin.ClerkGoogleSignInModule"]
}
}
43 changes: 43 additions & 0 deletions packages/expo-google-signin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "@clerk/expo-google-signin",
Comment thread
wobsoriano marked this conversation as resolved.
"version": "0.1.0",
"description": "Native Google Sign-In module to be used with Clerk for Expo",
"keywords": [
"react-native",
"expo",
"google-signin",
"clerk"
],
"homepage": "https://clerk.com/",
"bugs": {
"url": "https://github.com/clerk/javascript/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/clerk/javascript.git",
"directory": "packages/expo-google-signin"
},
"license": "MIT",
"author": "Clerk",
"files": [
"android",
"ios",
"expo-module.config.json",
"app.plugin.js",
"app.plugin.d.ts"
],
"scripts": {
"format": "node ../../scripts/format-package.mjs",
"format:check": "node ../../scripts/format-package.mjs --check"
},
"devDependencies": {
"@expo/config-plugins": "^54.0.4",
"expo": "~54.0.36"
},
"peerDependencies": {
"expo": ">=54 <58"
},
"publishConfig": {
"access": "public"
}
}
4 changes: 2 additions & 2 deletions packages/expo-passkeys/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
"@clerk/shared": "workspace:^"
},
"devDependencies": {
"expo": "~52.0.49"
"expo": "~54.0.36"
},
"peerDependencies": {
"expo": ">=53 <58",
"expo": ">=54 <58",
"react": "catalog:peer-react",
"react-native": "*"
}
Expand Down
7 changes: 0 additions & 7 deletions packages/expo/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ def clerkExpoVersion = clerkExpoPackageJson.version.toString()
// Dependency versions - centralized for easier updates
// See: https://docs.gradle.org/current/userguide/version_catalogs.html for app-level version catalogs
ext {
credentialsVersion = "1.3.0"
googleIdVersion = "1.1.1"
kotlinxCoroutinesVersion = "1.7.3"
clerkAndroidApiVersion = "1.0.36"
clerkAndroidUiVersion = "1.0.36"
Expand Down Expand Up @@ -104,11 +102,6 @@ try {
dependencies {
implementation project(':expo-modules-core')

// Credential Manager for Google Sign-In with nonce support
implementation "androidx.credentials:credentials:$credentialsVersion"
implementation "androidx.credentials:credentials-play-services-auth:$credentialsVersion"
implementation "com.google.android.libraries.identity.googleid:googleid:$googleIdVersion"

// Coroutines for async operations
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinxCoroutinesVersion"

Expand Down
34 changes: 0 additions & 34 deletions packages/expo/app.plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,45 +146,12 @@ const withClerkAndroid = config => {
});
};

/**
* Add Google Sign-In URL scheme to Info.plist (from main branch)
*/
const withClerkGoogleSignIn = config => {
const iosUrlScheme =
process.env.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME ||
(config.extra && config.extra.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME);

if (!iosUrlScheme) {
return config;
}

return withInfoPlist(config, modConfig => {
if (!Array.isArray(modConfig.modResults.CFBundleURLTypes)) {
modConfig.modResults.CFBundleURLTypes = [];
}

const schemeExists = modConfig.modResults.CFBundleURLTypes.some(urlType =>
urlType.CFBundleURLSchemes?.includes(iosUrlScheme),
);

if (!schemeExists) {
modConfig.modResults.CFBundleURLTypes.push({
CFBundleURLSchemes: [iosUrlScheme],
});
console.log(`✅ Added Google Sign-In URL scheme: ${iosUrlScheme}`);
}

return modConfig;
});
};

/**
* Combined Clerk Expo plugin
*
* When this plugin is configured in app.json/app.config.js:
* 1. iOS gets the deployment target and metadata required by Clerk native views
* 2. Android gets packaging exclusions for dependency conflicts
* 3. Google Sign-In URL scheme is configured (if env var is set)
*
* Native modules and views are registered via Expo Modules autolinking.
*/
Expand Down Expand Up @@ -345,7 +312,6 @@ const withClerkExpo = (config, props = {}) => {
if (appleSignIn !== false) {
config = withClerkAppleSignIn(config);
}
config = withClerkGoogleSignIn(config);
config = withClerkAndroid(config);
config = withClerkKeychainService(config, props);
config = withClerkTheme(config, props);
Expand Down
11 changes: 2 additions & 9 deletions packages/expo/expo-module.config.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
{
"platforms": ["apple", "android"],
"apple": {
"modules": [
"ClerkExpoModule",
"ClerkAuthViewModule",
"ClerkUserProfileViewModule",
"ClerkUserButtonViewModule",
"ClerkGoogleSignInModule"
]
"modules": ["ClerkExpoModule", "ClerkAuthViewModule", "ClerkUserProfileViewModule", "ClerkUserButtonViewModule"]
},
"android": {
"modules": [
"expo.modules.clerk.ClerkExpoModule",
"expo.modules.clerk.ClerkAuthViewModule",
"expo.modules.clerk.ClerkUserProfileViewModule",
"expo.modules.clerk.ClerkUserButtonViewModule",
"expo.modules.clerk.googlesignin.ClerkGoogleSignInModule"
"expo.modules.clerk.ClerkUserButtonViewModule"
]
}
}
Loading
Loading