From 93febf86870e007201bf47d1622d33ec8b0ee5ec Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 25 Feb 2026 13:50:55 -0800 Subject: [PATCH 1/5] [tools] Make it much easier to enter otp for dist-tags, stop dropping tags on promote [skip ci] --- tools/src/Npm.ts | 22 ++++++--- tools/src/NpmOtp.ts | 47 +++++++++++++++++++ tools/src/commands/PromotePackages.ts | 5 ++ tools/src/commands/PublishPackages.ts | 5 ++ .../promote-packages/tasks/promotePackages.ts | 33 ++++--------- tools/src/promote-packages/types.ts | 1 + .../tasks/assignTagForSdkRelease.ts | 8 +++- .../publish-packages/tasks/publishPackages.ts | 29 ++++++------ tools/src/publish-packages/types.ts | 1 + 9 files changed, 105 insertions(+), 46 deletions(-) create mode 100644 tools/src/NpmOtp.ts diff --git a/tools/src/Npm.ts b/tools/src/Npm.ts index cef6b3ba3414b8..8136980a358a23 100644 --- a/tools/src/Npm.ts +++ b/tools/src/Npm.ts @@ -151,6 +151,7 @@ export async function publishPackageAsync( if (options.dryRun) { args.push('--dry-run'); } + args.push(...maybeNpmOtpFlag()); await spawnAsync('npm', args, { cwd: packageDir, // Prevent expo-module-scripts from auto-adding --watch during lifecycle scripts @@ -185,18 +186,27 @@ export async function addTagAsync( } /** - * Removes package's tag with given name. + * Removes package's tag with given name. Silently ignores errors when the tag doesn't exist. */ export async function removeTagAsync( packageName: string, tagName: string, spawnOptions?: SpawnOptions ): Promise { - await spawnAsync( - 'npm', - ['dist-tag', 'rm', packageName, tagName, ...maybeNpmOtpFlag()], - spawnOptions - ); + try { + await spawnAsync( + 'npm', + ['dist-tag', 'rm', packageName, tagName, ...maybeNpmOtpFlag()], + spawnOptions + ); + } catch (error: any) { + const stderr = String(error?.stderr ?? ''); + if (/is not a dist-tag on/i.test(stderr)) { + // Tag doesn't exist, nothing to remove. + return; + } + throw error; + } } /** diff --git a/tools/src/NpmOtp.ts b/tools/src/NpmOtp.ts new file mode 100644 index 00000000000000..a1e678867534d1 --- /dev/null +++ b/tools/src/NpmOtp.ts @@ -0,0 +1,47 @@ +import inquirer from 'inquirer'; + +import logger from './Logger'; + +/** + * Returns true if the error is an npm OTP failure (expired/invalid/missing code). + */ +export function isOtpError(error: unknown): boolean { + const message = String((error as any)?.stderr ?? (error as any)?.message ?? ''); + return /EOTP|one-time pass/i.test(message); +} + +/** + * Prompts the user to enter an npm OTP code. + */ +export async function promptOtp(): Promise { + const { otp } = await inquirer.prompt([ + { + type: 'input', + name: 'otp', + message: 'Enter npm OTP code:', + }, + ]); + return otp.trim(); +} + +/** + * Runs an async function, re-prompting for a fresh OTP whenever the attempt + * fails due to an expired/invalid OTP code. Keeps retrying until the call + * succeeds or a non-OTP error is thrown. + */ +export async function withOtpRetry(fn: () => Promise): Promise { + // eslint-disable-next-line no-constant-condition + while (true) { + try { + await fn(); + return; + } catch (error) { + if (isOtpError(error)) { + logger.warn(' ⚠️ OTP expired or invalid, requesting a new code...'); + process.env.NPM_OTP = await promptOtp(); + } else { + throw error; + } + } + } +} diff --git a/tools/src/commands/PromotePackages.ts b/tools/src/commands/PromotePackages.ts index 63a77b99111495..61a64a39bf05a0 100644 --- a/tools/src/commands/PromotePackages.ts +++ b/tools/src/commands/PromotePackages.ts @@ -45,6 +45,11 @@ export default (program: Command) => { 'Promote packages in reverse alphabetical order (Z to A).', false ) + .option( + '--prompt-otp', + 'Prompt for an npm OTP code before promoting. Re-prompts automatically when the code expires.', + false + ) /* debug */ .option('-D, --dry', 'Whether to skip `npm dist-tag add` command.', false) diff --git a/tools/src/commands/PublishPackages.ts b/tools/src/commands/PublishPackages.ts index 600f52a3cf2428..60264ce2543c58 100644 --- a/tools/src/commands/PublishPackages.ts +++ b/tools/src/commands/PublishPackages.ts @@ -92,6 +92,11 @@ export default (program: Command) => { 'When retrying after a failed publish, auto-select all packages whose current version is not published yet and allow deselecting in a multi-select prompt.', false ) + .option( + '--prompt-otp', + 'Prompt for an npm OTP code before publishing. Re-prompts automatically when the code expires.', + false + ) /* debug options */ .option( '-S, --skip-repo-checks', diff --git a/tools/src/promote-packages/tasks/promotePackages.ts b/tools/src/promote-packages/tasks/promotePackages.ts index 75981d9fc5a1ae..5241cd4023d080 100644 --- a/tools/src/promote-packages/tasks/promotePackages.ts +++ b/tools/src/promote-packages/tasks/promotePackages.ts @@ -5,6 +5,7 @@ import { prepareParcels } from './prepareParcels'; import { selectPackagesToPromote } from './selectPackagesToPromote'; import logger from '../../Logger'; import * as Npm from '../../Npm'; +import { promptOtp, withOtpRetry } from '../../NpmOtp'; import { Task } from '../../TasksRunner'; import { formatVersionChange } from '../helpers'; import { CommandOptions, Parcel, TaskArgs } from '../types'; @@ -30,9 +31,10 @@ export const promotePackages = new Task( sorted.reverse(); } - // check if two factor auth is required for publishing - const npmProfile = await Npm.getProfileAsync(); - const requiresOTP = npmProfile?.tfa?.mode === 'auth-and-writes'; + // Prompt for OTP up front if requested; sets env var read by Npm.addTagAsync/removeTagAsync. + if (options.promptOtp) { + process.env.NPM_OTP = await promptOtp(); + } for (const { pkg, state } of sorted) { const currentVersion = pkg.packageVersion; @@ -49,28 +51,9 @@ export const promotePackages = new Task( // Tag the local version of the package. if (!options.dry) { - await Npm.addTagAsync(pkg.packageName, pkg.packageVersion, options.tag, { - stdio: requiresOTP ? 'inherit' : undefined, - }); - } - - // If the local version had any tags assigned, we can drop the old ones. - // If assigning `sdk-` tag, don't drop any other tags. This one is additive. - if ( - options.drop && - state.distTags && - !state.distTags.includes(options.tag) && - !options.tag.startsWith('sdk-') - ) { - for (const distTag of state.distTags) { - logger.log(' ', `Dropping ${yellow(distTag)} tag (${cyan(currentVersion)})...`); - - if (!options.dry) { - await Npm.removeTagAsync(pkg.packageName, distTag, { - stdio: requiresOTP ? 'inherit' : undefined, - }); - } - } + await withOtpRetry(() => + Npm.addTagAsync(pkg.packageName, pkg.packageVersion, options.tag) + ); } } diff --git a/tools/src/promote-packages/types.ts b/tools/src/promote-packages/types.ts index 42fc2dca03bdd8..ee696450a86c96 100644 --- a/tools/src/promote-packages/types.ts +++ b/tools/src/promote-packages/types.ts @@ -13,6 +13,7 @@ export type CommandOptions = { dry: boolean; list: boolean; reverse?: boolean; + promptOtp?: boolean; }; /** diff --git a/tools/src/publish-packages/tasks/assignTagForSdkRelease.ts b/tools/src/publish-packages/tasks/assignTagForSdkRelease.ts index 09a10f299ef837..ae0f659efbfeda 100644 --- a/tools/src/publish-packages/tasks/assignTagForSdkRelease.ts +++ b/tools/src/publish-packages/tasks/assignTagForSdkRelease.ts @@ -6,6 +6,7 @@ import { loadRequestedParcels } from './loadRequestedParcels'; import Git from '../../Git'; import logger from '../../Logger'; import * as Npm from '../../Npm'; +import { promptOtp, withOtpRetry } from '../../NpmOtp'; import { sdkVersionNumberAsync } from '../../ProjectVersions'; import { Task } from '../../TasksRunner'; import { runWithSpinner } from '../../Utils'; @@ -30,6 +31,11 @@ export const assignTagForSdkRelease = new Task( return; } + // Prompt for OTP up front if requested. + if (options.promptOtp) { + process.env.NPM_OTP = await promptOtp(); + } + await runWithSpinner( `Assigning ${yellow(sdkTag)} tag to packages`, async (step) => { @@ -53,7 +59,7 @@ export const assignTagForSdkRelease = new Task( ); if (!options.dry) { - await Npm.addTagAsync(pkgName, pkgVersion, sdkTag); + await withOtpRetry(() => Npm.addTagAsync(pkgName, pkgVersion, sdkTag)); } } }, diff --git a/tools/src/publish-packages/tasks/publishPackages.ts b/tools/src/publish-packages/tasks/publishPackages.ts index 6667ded3d63d66..18030673f5d89b 100644 --- a/tools/src/publish-packages/tasks/publishPackages.ts +++ b/tools/src/publish-packages/tasks/publishPackages.ts @@ -10,6 +10,7 @@ import { selectPackagesToPublish } from './selectPackagesToPublish'; import Git from '../../Git'; import logger from '../../Logger'; import * as Npm from '../../Npm'; +import { promptOtp, withOtpRetry } from '../../NpmOtp'; import { Package } from '../../Packages'; import { Task } from '../../TasksRunner'; import { sleepAsync } from '../../Utils'; @@ -30,9 +31,10 @@ export const publishPackages = new Task( const gitHead = await Git.getHeadCommitHashAsync(); - // check if two factor auth is required for publishing - const npmProfile = await Npm.getProfileAsync(); - const requiresOTP = npmProfile?.tfa?.mode === 'auth-and-writes'; + // Prompt for OTP up front if requested; sets env var read by Npm commands. + if (options.promptOtp) { + process.env.NPM_OTP = await promptOtp(); + } for (const { pkg, state } of parcels) { const packageJsonPath = path.join(pkg.path, 'package.json'); @@ -58,23 +60,22 @@ export const publishPackages = new Task( // Publish the package. try { - await Npm.publishPackageAsync(pkg.path, { - source: packageSource, - tagName: options.tag, - dryRun: options.dry, - spawnOptions: { - stdio: requiresOTP ? 'inherit' : undefined, - }, - }); + await withOtpRetry(() => + Npm.publishPackageAsync(pkg.path, { + source: packageSource, + tagName: options.tag, + dryRun: options.dry, + }) + ); // Assign SDK tag when package is a template if (pkg.isTemplate() && !options.canary) { const sdkTag = `sdk-${semver.major(releaseVersion)}`; logger.log(' ', `Assigning ${yellow(sdkTag)} tag to ${green(pkg.packageName)}`); if (!options.dry) { await sleepAsync(1000); // wait for npm to process the package - await Npm.addTagAsync(pkg.packageName, releaseVersion, sdkTag, { - stdio: requiresOTP ? 'inherit' : undefined, - }); + await withOtpRetry(() => + Npm.addTagAsync(pkg.packageName, releaseVersion, sdkTag) + ); } } } catch (error) { diff --git a/tools/src/publish-packages/types.ts b/tools/src/publish-packages/types.ts index 5d0f20969a60b1..d09609cc13fbef 100644 --- a/tools/src/publish-packages/types.ts +++ b/tools/src/publish-packages/types.ts @@ -36,6 +36,7 @@ export type CommandOptions = { grantAccess: boolean; checkIntegrity: boolean; assignSdkTag: boolean; + promptOtp?: boolean; }; /** From 5b34e1db573af84d0503b1db169a181d5852c896 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 25 Feb 2026 14:18:42 -0800 Subject: [PATCH 2/5] Revert "[expo-router] Move react-native-screens from dependencies to peerDependencies (#43394)" This reverts commit 436bed646065bb0ca95cbdbd267459d11f3654a9. --- packages/expo-router/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/expo-router/package.json b/packages/expo-router/package.json index 0344799270dda6..3c7bf8d1e8e055 100644 --- a/packages/expo-router/package.json +++ b/packages/expo-router/package.json @@ -95,7 +95,6 @@ "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", - "react-native-screens": "~4.24.0", "react-native-web": "*", "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, @@ -153,7 +152,7 @@ "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.2.1", - "react-native-screens": "~4.24.0", + "react-native-screens": "4.24.0", "semver": "~7.6.3", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", From 261916942287d8626a21cf035d98f161a74ada68 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 25 Feb 2026 14:18:54 -0800 Subject: [PATCH 3/5] Revert "Upgrade screens to 4.24.0 (#43379)" This reverts commit b7db1570aea585a2550bdccb38d70dc00a59b9ab. --- apps/bare-expo/ios/Podfile.lock | 8 ++++---- apps/bare-expo/package.json | 2 +- apps/brownfield-tester/expo-app/package.json | 2 +- apps/expo-go/ios/Podfile.lock | 8 ++++---- apps/expo-go/package.json | 2 +- apps/native-component-list/package.json | 2 +- apps/notification-tester/package.json | 2 +- apps/router-e2e/package.json | 2 +- .../e2e/fixtures/with-monorepo/apps/app-a/package.json | 2 +- .../e2e/fixtures/with-monorepo/apps/app-b/package.json | 2 +- .../e2e/fixtures/with-router-typed-routes/package.json | 2 +- .../@expo/cli/e2e/fixtures/with-router/package.json | 2 +- packages/expo-router/CHANGELOG.md | 2 -- .../ios/LinkPreview/LinkPreviewNativeNavigation.swift | 10 +++++----- packages/expo-router/package.json | 2 +- packages/expo/bundledNativeModules.json | 2 +- templates/expo-template-default/package.json | 2 +- templates/expo-template-tabs/package.json | 2 +- yarn.lock | 8 ++++---- 19 files changed, 31 insertions(+), 33 deletions(-) diff --git a/apps/bare-expo/ios/Podfile.lock b/apps/bare-expo/ios/Podfile.lock index d551dd45987912..a012c2ebcd1563 100644 --- a/apps/bare-expo/ios/Podfile.lock +++ b/apps/bare-expo/ios/Podfile.lock @@ -2947,7 +2947,7 @@ PODS: - ReactNativeDependencies - RNWorklets - Yoga - - RNScreens (4.24.0): + - RNScreens (4.23.0): - hermes-engine - RCTRequired - RCTTypeSafety @@ -2969,9 +2969,9 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - ReactNativeDependencies - - RNScreens/common (= 4.24.0) + - RNScreens/common (= 4.23.0) - Yoga - - RNScreens/common (4.24.0): + - RNScreens/common (4.23.0): - hermes-engine - RCTRequired - RCTTypeSafety @@ -3980,7 +3980,7 @@ SPEC CHECKSUMS: RNDateTimePicker: 5e0666de98f1edfac67ee7dde6be8a5415e487a0 RNGestureHandler: 8e4a9372425d4caa9e3da5072a8dda7a54ed1097 RNReanimated: 61462806110686a6f5d7c45c6f910cf73cd57dd9 - RNScreens: 088d923c4327c63c9f8c942cae17a9d038f47d97 + RNScreens: fb11b7412bcbdc0ffafcaf9174938d998d4e2bc4 RNSVG: b5bd4454de003a99d3130a3c6a1b1c949c89d37d RNWorklets: 87faff8e75d34d1240c75189e490e92901dd3544 SDWebImage: f29024626962457f3470184232766516dee8dfea diff --git a/apps/bare-expo/package.json b/apps/bare-expo/package.json index ae9c1f1200d2af..7c1a9cce8cbe21 100644 --- a/apps/bare-expo/package.json +++ b/apps/bare-expo/package.json @@ -76,7 +76,7 @@ "react-native-reanimated": "4.2.1", "react-native-safe-area-context": "5.6.2", "react-native-svg": "15.15.3", - "react-native-screens": "4.24.0", + "react-native-screens": "4.23.0", "react-native-view-shot": "4.0.3", "react-native-webview": "13.16.0", "react-native-worklets": "0.7.2", diff --git a/apps/brownfield-tester/expo-app/package.json b/apps/brownfield-tester/expo-app/package.json index aa55398feebf42..283f0ec78d3702 100644 --- a/apps/brownfield-tester/expo-app/package.json +++ b/apps/brownfield-tester/expo-app/package.json @@ -35,7 +35,7 @@ "react-native-worklets": "0.7.2", "react-native-reanimated": "~4.2.1", "react-native-safe-area-context": "~5.6.2", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" }, "devDependencies": { diff --git a/apps/expo-go/ios/Podfile.lock b/apps/expo-go/ios/Podfile.lock index 2308bebd7ab1e8..c29da968c564df 100644 --- a/apps/expo-go/ios/Podfile.lock +++ b/apps/expo-go/ios/Podfile.lock @@ -3732,7 +3732,7 @@ PODS: - RNWorklets - SocketRocket - Yoga - - RNScreens (4.24.0): + - RNScreens (4.23.0): - boost - DoubleConversion - fast_float @@ -3759,10 +3759,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNScreens/common (= 4.24.0) + - RNScreens/common (= 4.23.0) - SocketRocket - Yoga - - RNScreens/common (4.24.0): + - RNScreens/common (4.23.0): - boost - DoubleConversion - fast_float @@ -4857,7 +4857,7 @@ SPEC CHECKSUMS: RNDateTimePicker: e9e210197c267461f70f3f47bec705401ff72077 RNGestureHandler: 77eecab5fd636666ca73a55bb61e2f1a685b7e84 RNReanimated: 31da8d5f1605f5367e2392748ba9f4ba6eaf1178 - RNScreens: 7179cc1ba31b4e18ed29f10abf20c24a7961cf4c + RNScreens: ec8bdc9f024d5828e5adf4f5e8870d5260cff616 RNSVG: 8744ec9d5c0ca0f51cdd7a577c30ce01cd3d76b0 RNWorklets: 8e934a6b6d5a2710b9250e63a18a2d2f8b875a18 SDWebImage: f29024626962457f3470184232766516dee8dfea diff --git a/apps/expo-go/package.json b/apps/expo-go/package.json index 5113bc099da40b..65b499ce58aa78 100644 --- a/apps/expo-go/package.json +++ b/apps/expo-go/package.json @@ -78,7 +78,7 @@ "react-native-reanimated": "4.2.1", "react-native-safe-area-context": "5.6.2", "react-native-svg": "15.15.3", - "react-native-screens": "4.24.0", + "react-native-screens": "4.23.0", "react-native-view-shot": "4.0.3", "react-native-webview": "13.16.0", "react-native-worklets": "0.7.2", diff --git a/apps/native-component-list/package.json b/apps/native-component-list/package.json index c42f0b1a0f0603..7fa1853f19a434 100644 --- a/apps/native-component-list/package.json +++ b/apps/native-component-list/package.json @@ -153,7 +153,7 @@ "react-native-reanimated": "4.2.1", "react-native-safe-area-context": "5.6.2", "react-native-svg": "15.15.3", - "react-native-screens": "4.24.0", + "react-native-screens": "4.23.0", "react-native-view-shot": "4.0.3", "react-native-web": "~0.21.0", "react-native-webview": "13.16.0", diff --git a/apps/notification-tester/package.json b/apps/notification-tester/package.json index 02da6973fcf83f..8ab2a0fbfc6453 100644 --- a/apps/notification-tester/package.json +++ b/apps/notification-tester/package.json @@ -36,7 +36,7 @@ "react": "19.2.0", "react-native": "0.83.2", "react-native-safe-area-context": "5.6.2", - "react-native-screens": "4.24.0" + "react-native-screens": "4.23.0" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/apps/router-e2e/package.json b/apps/router-e2e/package.json index d087cf0742b36c..bd563908b66094 100644 --- a/apps/router-e2e/package.json +++ b/apps/router-e2e/package.json @@ -71,7 +71,7 @@ "react": "19.2.0", "react-native": "0.83.2", "react-native-safe-area-context": "5.6.2", - "react-native-screens": "4.24.0", + "react-native-screens": "4.23.0", "react-native-webview": "13.16.0" }, "devDependencies": { diff --git a/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-a/package.json b/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-a/package.json index 8cb1bdc5253443..3fe613fbe2767f 100644 --- a/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-a/package.json +++ b/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-a/package.json @@ -13,7 +13,7 @@ "react-dom": "19.2.0", "react-native": "0.83.2", "react-native-safe-area-context": "~5.6.2", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" } } diff --git a/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-b/package.json b/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-b/package.json index 75c5f5b0d3baf2..c75a38a3bc2a50 100644 --- a/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-b/package.json +++ b/packages/@expo/cli/e2e/fixtures/with-monorepo/apps/app-b/package.json @@ -13,7 +13,7 @@ "react-dom": "19.2.0", "react-native": "0.83.2", "react-native-safe-area-context": "~5.6.2", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" } } diff --git a/packages/@expo/cli/e2e/fixtures/with-router-typed-routes/package.json b/packages/@expo/cli/e2e/fixtures/with-router-typed-routes/package.json index 6d3515573bbfd1..ca6e430291d126 100644 --- a/packages/@expo/cli/e2e/fixtures/with-router-typed-routes/package.json +++ b/packages/@expo/cli/e2e/fixtures/with-router-typed-routes/package.json @@ -13,7 +13,7 @@ "react-dom": "19.2.0", "react-native": "0.83.2", "react-native-safe-area-context": "~5.6.2", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" } } diff --git a/packages/@expo/cli/e2e/fixtures/with-router/package.json b/packages/@expo/cli/e2e/fixtures/with-router/package.json index 3d2252cdead088..daf3a2eea144a3 100644 --- a/packages/@expo/cli/e2e/fixtures/with-router/package.json +++ b/packages/@expo/cli/e2e/fixtures/with-router/package.json @@ -12,7 +12,7 @@ "react-dom": "19.2.0", "react-native": "0.83.2", "react-native-safe-area-context": "~5.6.2", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" } } diff --git a/packages/expo-router/CHANGELOG.md b/packages/expo-router/CHANGELOG.md index ea77e08e78aa33..35be720faf92ca 100644 --- a/packages/expo-router/CHANGELOG.md +++ b/packages/expo-router/CHANGELOG.md @@ -29,8 +29,6 @@ ### 💡 Others -- Pin screens to 4.24.0 ([#43379](https://github.com/expo/expo/pull/43379) by [@Ubax](https://github.com/Ubax)) - ## 55.0.0-preview.9 — 2026-02-20 ### 🎉 New features diff --git a/packages/expo-router/ios/LinkPreview/LinkPreviewNativeNavigation.swift b/packages/expo-router/ios/LinkPreview/LinkPreviewNativeNavigation.swift index 76aa6b595c705e..d958ec1c6e33e3 100644 --- a/packages/expo-router/ios/LinkPreview/LinkPreviewNativeNavigation.swift +++ b/packages/expo-router/ios/LinkPreview/LinkPreviewNativeNavigation.swift @@ -48,7 +48,7 @@ internal class LinkPreviewNativeNavigation { guard let stackOrTabView else { return } - if let tabView = stackOrTabView as? RNSTabsScreenComponentView { + if let tabView = stackOrTabView as? RNSBottomTabsScreenComponentView { let newTabKeys = tabPath?.path.map { $0.newTabKey } ?? [] // The order is important here. findStackViewWithScreenIdInSubViews must be called // even if screenId is nil to compute the tabChangeCommands. @@ -150,7 +150,7 @@ internal class LinkPreviewNativeNavigation { if let result = enumeratedViews .first(where: { _, view in - guard let tabView = view as? RNSTabsScreenComponentView, let tabKey = tabView.tabKey + guard let tabView = view as? RNSBottomTabsScreenComponentView, let tabKey = tabView.tabKey else { return false } @@ -162,10 +162,10 @@ internal class LinkPreviewNativeNavigation { } private func getTabBarControllerFromTabView(view: UIView) -> UITabBarController? { - if let tabScreenView = view as? RNSTabsScreenComponentView { + if let tabScreenView = view as? RNSBottomTabsScreenComponentView { return tabScreenView.reactViewController()?.tabBarController as? UITabBarController } - if let tabHostView = view as? RNSTabsHostComponentView { + if let tabHostView = view as? RNSBottomTabsHostComponentView { return tabHostView.controller as? UITabBarController } return nil @@ -182,7 +182,7 @@ internal class LinkPreviewNativeNavigation { if view.screenIds.contains(screenId) { return view } - } else if let tabView = nextResponder as? RNSTabsScreenComponentView { + } else if let tabView = nextResponder as? RNSBottomTabsScreenComponentView { if let tabKey = tabView.tabKey, tabKeys.contains(tabKey) { return tabView } diff --git a/packages/expo-router/package.json b/packages/expo-router/package.json index 3c7bf8d1e8e055..caca2b3b94c857 100644 --- a/packages/expo-router/package.json +++ b/packages/expo-router/package.json @@ -95,6 +95,7 @@ "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", + "react-native-screens": "*", "react-native-web": "*", "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, @@ -152,7 +153,6 @@ "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.2.1", - "react-native-screens": "4.24.0", "semver": "~7.6.3", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", diff --git a/packages/expo/bundledNativeModules.json b/packages/expo/bundledNativeModules.json index 0f29d8de49c8da..d1c43ad59b0513 100644 --- a/packages/expo/bundledNativeModules.json +++ b/packages/expo/bundledNativeModules.json @@ -104,7 +104,7 @@ "react-native-pager-view": "8.0.0", "react-native-worklets": "0.7.2", "react-native-reanimated": "~4.2.1", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-safe-area-context": "~5.6.2", "react-native-svg": "15.15.3", "react-native-view-shot": "4.0.3", diff --git a/templates/expo-template-default/package.json b/templates/expo-template-default/package.json index 3dfa1917628d22..851523c5ee69c2 100644 --- a/templates/expo-template-default/package.json +++ b/templates/expo-template-default/package.json @@ -36,7 +36,7 @@ "react-native-worklets": "0.7.2", "react-native-reanimated": "~4.2.1", "react-native-safe-area-context": "~5.6.2", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" }, "devDependencies": { diff --git a/templates/expo-template-tabs/package.json b/templates/expo-template-tabs/package.json index 8a9da739b2ad8c..7923a7ce5ed734 100644 --- a/templates/expo-template-tabs/package.json +++ b/templates/expo-template-tabs/package.json @@ -27,7 +27,7 @@ "react-native-worklets": "0.7.2", "react-native-reanimated": "~4.2.1", "react-native-safe-area-context": "~5.6.2", - "react-native-screens": "~4.24.0", + "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index b2770f2d1e8afa..7cf9bc6e5835b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13425,10 +13425,10 @@ react-native-screens@4.11.1-nightly-20250611-8b82e081e: react-native-is-edge-to-edge "^1.1.7" warn-once "^0.1.0" -react-native-screens@4.24.0, react-native-screens@~4.24.0: - version "4.24.0" - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-4.24.0.tgz#dbe8f610b5d2e31f71425d2ea3caaff1b9a7e2de" - integrity sha512-SyoiGaDofiyGPFrUkn1oGsAzkRuX1JUvTD9YQQK3G1JGQ5VWkvHgYSsc1K9OrLsDQxN7NmV71O0sHCAh8cBetA== +react-native-screens@4.23.0, react-native-screens@~4.23.0: + version "4.23.0" + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-4.23.0.tgz#81574b1b0cc4ac6c9ed63e46eca7126f37affe86" + integrity sha512-XhO3aK0UeLpBn4kLecd+J+EDeRRJlI/Ro9Fze06vo1q163VeYtzfU9QS09/VyDFMWR1qxDC1iazCArTPSFFiPw== dependencies: react-freeze "^1.0.0" warn-once "^0.1.0" From 2c64515dac17b419e82a30d5df477d5ad6dad2b3 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 25 Feb 2026 14:19:31 -0800 Subject: [PATCH 4/5] [expo] Bundle Reanimated 4.2.1 exactly, 4.2.2 has incompatible C++ [skip ci] --- packages/expo/bundledNativeModules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/expo/bundledNativeModules.json b/packages/expo/bundledNativeModules.json index d1c43ad59b0513..4b5a5137686af6 100644 --- a/packages/expo/bundledNativeModules.json +++ b/packages/expo/bundledNativeModules.json @@ -103,7 +103,7 @@ "react-native-maps": "1.26.20", "react-native-pager-view": "8.0.0", "react-native-worklets": "0.7.2", - "react-native-reanimated": "~4.2.1", + "react-native-reanimated": "4.2.1", "react-native-screens": "~4.23.0", "react-native-safe-area-context": "~5.6.2", "react-native-svg": "15.15.3", From 52a9db397dc62ebee3bce124bf5a0f7c8b3b7cdc Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 25 Feb 2026 14:21:35 -0800 Subject: [PATCH 5/5] Publish packages patch-project@55.1.7 expo-router@55.0.2 expo-doctor@1.18.8 expo@55.0.2 expo-template-tabs@55.1.9 expo-template-default@55.1.9 expo-template-blank-typescript@55.1.9 expo-template-blank@55.1.9 expo-template-bare-minimum@55.0.14 --- apps/bare-expo/ios/Podfile.lock | 16 ++++++++-------- apps/bare-expo/package.json | 4 ++-- apps/brownfield-tester/expo-app/package.json | 4 ++-- apps/expo-go/ios/Podfile.lock | 12 ++++++------ apps/expo-go/package.json | 4 ++-- apps/jest-expo-mock-generator/package.json | 2 +- apps/minimal-tester/package.json | 2 +- apps/native-component-list/package.json | 2 +- apps/native-tests/package.json | 2 +- apps/notification-tester/package.json | 4 ++-- apps/router-e2e/package.json | 4 ++-- apps/sandbox/package.json | 4 ++-- apps/test-suite/package.json | 2 +- packages/expo-doctor/CHANGELOG.md | 4 ++++ packages/expo-doctor/package.json | 2 +- packages/expo-module-template/$package.json | 2 +- packages/expo-router/CHANGELOG.md | 4 ++++ packages/expo-router/android/build.gradle | 4 ++-- packages/expo-router/package.json | 2 +- packages/expo/CHANGELOG.md | 4 ++++ packages/expo/android/build.gradle | 4 ++-- packages/expo/bundledNativeModules.json | 2 +- packages/expo/package.json | 2 +- packages/patch-project/CHANGELOG.md | 4 ++++ packages/patch-project/package.json | 2 +- .../expo-template-bare-minimum/package.json | 4 ++-- .../expo-template-blank-typescript/package.json | 4 ++-- templates/expo-template-blank/package.json | 4 ++-- templates/expo-template-default/package.json | 8 ++++---- templates/expo-template-tabs/package.json | 8 ++++---- 30 files changed, 71 insertions(+), 55 deletions(-) diff --git a/apps/bare-expo/ios/Podfile.lock b/apps/bare-expo/ios/Podfile.lock index a012c2ebcd1563..6d3fbb01c1c598 100644 --- a/apps/bare-expo/ios/Podfile.lock +++ b/apps/bare-expo/ios/Podfile.lock @@ -38,7 +38,7 @@ PODS: - EXManifests/Tests (55.0.9): - ExpoModulesCore - ExpoModulesTestCore - - Expo (55.0.1): + - Expo (55.0.2): - ExpoModulesCore - hermes-engine - RCTRequired @@ -297,7 +297,7 @@ PODS: - ReactCommon/turbomodule/core - ReactNativeDependencies - Yoga - - Expo/Tests (55.0.1): + - Expo/Tests (55.0.2): - ExpoModulesCore - hermes-engine - RCTRequired @@ -529,7 +529,7 @@ PODS: - ExpoModulesTestCore - ExpoPrint (55.0.8): - ExpoModulesCore - - ExpoRouter (55.0.1): + - ExpoRouter (55.0.2): - ExpoModulesCore - RNScreens - ExpoScreenCapture (55.0.8): @@ -3809,7 +3809,7 @@ SPEC CHECKSUMS: EXConstants: a16ad8db13865e97aaecf64bb92e8ad8e8ce1ae8 EXJSONUtils: 0080c14b673cfa9a6be5e3fe429768ffe3d42dfb EXManifests: 22ec6b0abf4e9b54ea22624aa955cf68d6c90590 - Expo: 542aada019f99dbcd3675ebe0f3e070d6eb0c349 + Expo: 2ad467b934a08a990484d7265fd37fd50b8d4b54 expo-dev-client: de1af4570c4d213e52b700f701914521270ad93d expo-dev-launcher: 393a0d0d91dfcd7d38d9744ccb2e3648c8d5a258 expo-dev-menu: 1eed01e48a4d17539c04dd3d5c8d68c62f64daaa @@ -3862,7 +3862,7 @@ SPEC CHECKSUMS: ExpoNetwork: 018e4e16afdaff30c5002fadf64daab55bc20de0 ExpoNotifications: 0293112699b35aa26f6e9e1fcecee0323f3187dc ExpoPrint: 744a2ca8033698b749389290d96f4ec836027aed - ExpoRouter: 7976ca087cc8e88f5581bc81df29d1644ea6dfb9 + ExpoRouter: 98f1ec6dfbde5edb827aa411681c1fcbee07786f ExpoScreenCapture: a4b2159b48fd2514a99f426778da31d1f0a9736f ExpoScreenOrientation: e042b7f121c3b3463f9486189785d568ff57739e ExpoSecureStore: 7837b892a89ad8d28b64d9302b657e8b6ebae250 @@ -3885,7 +3885,7 @@ SPEC CHECKSUMS: EXUpdates: c5a64985f393cf4f8beb4463f86a885c90b4fccc EXUpdatesInterface: 26412751a0f7a7130614655929e316f684552aab FBLazyVector: 32e9ed0301d0fcbc1b2b341dd7fcbf291f51eb83 - hermes-engine: 1566042511e927d64254f2efe08ae744a5eb9a00 + hermes-engine: 9e7dfb4eb5867a67fb30760f9f6f8646b9f77d28 libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 @@ -3903,7 +3903,7 @@ SPEC CHECKSUMS: React: f4edc7518ccb0b54a6f580d89dd91471844b4990 React-callinvoker: 79ef4e3f1c021571f6d2dafbe45ca432b2f3a146 React-Core: 469995a2b6ef0ffff38ed123ccd202287703939e - React-Core-prebuilt: e71199b350bcaeade83eea6e463e818dcc46d718 + React-Core-prebuilt: b5ea7a06af79de343ee95cb48e56d682a29763ab React-CoreModules: db3b65cb984dfc7e0b00db517712cff8d938fc3f React-cxxreact: 8551bebcc6bc624ce774dccae20c383844aa9d06 React-debug: 4f6739c820d7da9c20f48caa985573b6a847e5f5 @@ -3973,7 +3973,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: 1976cdf5076a7e34718a56ead2f2069c7f54ebe9 ReactCodegen: 4e2863f450e4aec6b66a7e91d41a209aa4601c97 ReactCommon: 696163beb1630cf1f7590dbc8bfc542e40bdbe76 - ReactNativeDependencies: d804b447c01215d21137868e3b5b5a920fc9f7f4 + ReactNativeDependencies: 5dd7d57944d42324ba59e9c95ae58b4f7c7a9882 RNCAsyncStorage: e85a99325df9eb0191a6ee2b2a842644c7eb29f4 RNCMaskedView: 3c9d7586e2b9bbab573591dcb823918bc4668005 RNCPicker: e0149590451d5eae242cf686014a6f6d808f93c7 diff --git a/apps/bare-expo/package.json b/apps/bare-expo/package.json index 7c1a9cce8cbe21..a9d564ab8451ab 100644 --- a/apps/bare-expo/package.json +++ b/apps/bare-expo/package.json @@ -53,7 +53,7 @@ "@react-native-segmented-control/segmented-control": "2.5.7", "@shopify/flash-list": "2.0.2", "@shopify/react-native-skia": "2.4.18", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-brownfield": "~55.0.11", "expo-build-properties": "~55.0.9", "expo-camera": "~55.0.9", @@ -62,7 +62,7 @@ "expo-insights": "~55.0.10", "expo-network-addons": "~55.0.8", "expo-notifications": "~55.0.10", - "expo-router": "~55.0.1", + "expo-router": "~55.0.2", "expo-splash-screen": "~55.0.9", "lottie-react-native": "^7.3.4", "native-component-list": "*", diff --git a/apps/brownfield-tester/expo-app/package.json b/apps/brownfield-tester/expo-app/package.json index 283f0ec78d3702..4932ba49ba9d1f 100644 --- a/apps/brownfield-tester/expo-app/package.json +++ b/apps/brownfield-tester/expo-app/package.json @@ -13,7 +13,7 @@ "@react-navigation/bottom-tabs": "^7.7.3", "@react-navigation/elements": "^2.8.1", "@react-navigation/native": "^7.1.28", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-brownfield": "~55.0.11", "expo-constants": "~55.0.7", "expo-device": "~55.0.9", @@ -22,7 +22,7 @@ "expo-glass-effect": "~55.0.7", "expo-image": "~55.0.5", "expo-linking": "~55.0.7", - "expo-router": "~55.0.1", + "expo-router": "~55.0.2", "expo-splash-screen": "~55.0.9", "expo-status-bar": "~55.0.4", "expo-symbols": "~55.0.4", diff --git a/apps/expo-go/ios/Podfile.lock b/apps/expo-go/ios/Podfile.lock index c29da968c564df..01d8227dde525a 100644 --- a/apps/expo-go/ios/Podfile.lock +++ b/apps/expo-go/ios/Podfile.lock @@ -20,7 +20,7 @@ PODS: - EXManifests/Tests (55.0.9): - ExpoModulesCore - ExpoModulesTestCore - - Expo (55.0.1): + - Expo (55.0.2): - boost - DoubleConversion - ExpoModulesCore @@ -113,7 +113,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - Expo/Tests (55.0.1): + - Expo/Tests (55.0.2): - boost - DoubleConversion - ExpoModulesCore @@ -333,7 +333,7 @@ PODS: - ExpoModulesTestCore - ExpoPrint (55.0.8): - ExpoModulesCore - - ExpoRouter (55.0.1): + - ExpoRouter (55.0.2): - ExpoModulesCore - RNScreens - ExpoScreenCapture (55.0.8): @@ -4677,7 +4677,7 @@ SPEC CHECKSUMS: EXConstants: a16ad8db13865e97aaecf64bb92e8ad8e8ce1ae8 EXJSONUtils: 0080c14b673cfa9a6be5e3fe429768ffe3d42dfb EXManifests: 22ec6b0abf4e9b54ea22624aa955cf68d6c90590 - Expo: e544060eeb863a5ec3b8c9fb8edc98c1f57c8972 + Expo: 32293c3c6a3ed43a7df7f735452b34b6492ac4b8 expo-dev-menu: 5088d5e44ace01845dcb5f15d58f8a62defb4d2d expo-dev-menu-interface: bf6f816d29b45bec038080790963c635e8d588c2 ExpoAgeRange: 5e8b40e46734155b4b974d4d331ea3a156d82d94 @@ -4724,7 +4724,7 @@ SPEC CHECKSUMS: ExpoNetwork: 018e4e16afdaff30c5002fadf64daab55bc20de0 ExpoNotifications: 0293112699b35aa26f6e9e1fcecee0323f3187dc ExpoPrint: 744a2ca8033698b749389290d96f4ec836027aed - ExpoRouter: 7976ca087cc8e88f5581bc81df29d1644ea6dfb9 + ExpoRouter: 98f1ec6dfbde5edb827aa411681c1fcbee07786f ExpoScreenCapture: a4b2159b48fd2514a99f426778da31d1f0a9736f ExpoScreenOrientation: ba181744c7ac781952da30c3c2b8d7661df21446 ExpoSecureStore: 7837b892a89ad8d28b64d9302b657e8b6ebae250 @@ -4759,7 +4759,7 @@ SPEC CHECKSUMS: GoogleAppMeasurement: 8a82b93a6400c8e6551c0bcd66a9177f2e067aed GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d - hermes-engine: d59202edb9173c808259b0945bb161d1e24963f0 + hermes-engine: ca6495d9d859ae100566305c4d0afe7a0c777a46 libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 diff --git a/apps/expo-go/package.json b/apps/expo-go/package.json index 65b499ce58aa78..f018be553fe36f 100644 --- a/apps/expo-go/package.json +++ b/apps/expo-go/package.json @@ -43,7 +43,7 @@ "date-fns": "^2.28.0", "dedent": "^0.7.0", "es6-error": "^4.1.1", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-application": "~55.0.8", "expo-asset": "~55.0.7", "expo-blur": "~55.0.8", @@ -55,7 +55,7 @@ "expo-linking": "^55.0.7", "expo-location": "~55.1.2", "expo-notifications": "~55.0.10", - "expo-router": "~55.0.1", + "expo-router": "~55.0.2", "expo-splash-screen": "~55.0.9", "expo-store-review": "~55.0.8", "expo-task-manager": "~55.0.9", diff --git a/apps/jest-expo-mock-generator/package.json b/apps/jest-expo-mock-generator/package.json index 4870ba40222f69..78904e9fdb20d1 100644 --- a/apps/jest-expo-mock-generator/package.json +++ b/apps/jest-expo-mock-generator/package.json @@ -6,7 +6,7 @@ "main": "index.js", "dependencies": { "@expo/mux": "^1.0.7", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-clipboard": "~55.0.8", "react": "19.2.0", "react-native": "0.83.2" diff --git a/apps/minimal-tester/package.json b/apps/minimal-tester/package.json index 26a54f23cccd47..fc9c4a335a2868 100644 --- a/apps/minimal-tester/package.json +++ b/apps/minimal-tester/package.json @@ -9,7 +9,7 @@ "eject": "expo eject" }, "dependencies": { - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-apple-authentication": "~55.0.8", "expo-blur": "~55.0.8", "expo-brownfield": "~55.0.11", diff --git a/apps/native-component-list/package.json b/apps/native-component-list/package.json index 7fa1853f19a434..c8f112bbc4dfc2 100644 --- a/apps/native-component-list/package.json +++ b/apps/native-component-list/package.json @@ -57,7 +57,7 @@ "@shopify/react-native-skia": "2.4.18", "date-format": "^2.0.0", "deep-object-diff": "^1.1.9", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-2d-context": "^0.0.4", "expo-age-range": "~0.2.10", "expo-apple-authentication": "~55.0.8", diff --git a/apps/native-tests/package.json b/apps/native-tests/package.json index 02bf59a98dadc2..eb30b27d21070c 100644 --- a/apps/native-tests/package.json +++ b/apps/native-tests/package.json @@ -9,7 +9,7 @@ "web": "expo start --web" }, "dependencies": { - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-clipboard": "55.0.8", "expo-dev-client": "~55.0.9", "expo-image": "~55.0.5", diff --git a/apps/notification-tester/package.json b/apps/notification-tester/package.json index 8ab2a0fbfc6453..28cc251df49d96 100644 --- a/apps/notification-tester/package.json +++ b/apps/notification-tester/package.json @@ -20,11 +20,11 @@ "dependencies": { "@react-navigation/bottom-tabs": "^7.7.3", "@react-navigation/native": "^7.1.28", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-font": "55.0.4", "expo-linking": "55.0.7", "expo-localization": "55.0.8", - "expo-router": "55.0.1", + "expo-router": "55.0.2", "expo-device": "55.0.9", "expo-constants": "55.0.7", "expo-dev-client": "~55.0.9", diff --git a/apps/router-e2e/package.json b/apps/router-e2e/package.json index bd563908b66094..5cc3323f557ee7 100644 --- a/apps/router-e2e/package.json +++ b/apps/router-e2e/package.json @@ -60,10 +60,10 @@ "dependencies": { "@expo/dom-webview": "55.0.3", "@expo/vector-icons": "^15.0.2", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-haptics": "~55.0.8", "expo-linking": "~55.0.7", - "expo-router": "^55.0.1", + "expo-router": "^55.0.2", "expo-speech": "~55.0.8", "expo-sqlite": "~55.0.10", "expo-symbols": "~55.0.4", diff --git a/apps/sandbox/package.json b/apps/sandbox/package.json index 257a32283688ba..ad6845db4cd62f 100644 --- a/apps/sandbox/package.json +++ b/apps/sandbox/package.json @@ -10,9 +10,9 @@ "dependencies": { "@react-navigation/bottom-tabs": "^7.3.10", "@react-navigation/native": "^7.1.6", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-linking": "~55.0.7", - "expo-router": "^55.0.1", + "expo-router": "^55.0.2", "expo-splash-screen": "~55.0.9", "react": "19.1.1", "react-native": "0.83.2", diff --git a/apps/test-suite/package.json b/apps/test-suite/package.json index d9e848f2c75706..d51dbb7e5333fc 100644 --- a/apps/test-suite/package.json +++ b/apps/test-suite/package.json @@ -15,7 +15,7 @@ "@react-navigation/native": "^7.1.28", "@react-navigation/stack": "^7.6.7", "async-retry": "^1.1.4", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-application": "~55.0.8", "expo-asset": "~55.0.7", "expo-background-fetch": "~55.0.8", diff --git a/packages/expo-doctor/CHANGELOG.md b/packages/expo-doctor/CHANGELOG.md index 4694a3dcce08ed..8ba9d7b88623a7 100644 --- a/packages/expo-doctor/CHANGELOG.md +++ b/packages/expo-doctor/CHANGELOG.md @@ -10,6 +10,10 @@ ### 💡 Others +## 1.18.8 — 2026-02-25 + +_This version does not introduce any user-facing changes._ + ## 1.18.7 — 2026-02-20 _This version does not introduce any user-facing changes._ diff --git a/packages/expo-doctor/package.json b/packages/expo-doctor/package.json index 87fa3956896c88..4f714be33a9e6d 100644 --- a/packages/expo-doctor/package.json +++ b/packages/expo-doctor/package.json @@ -1,6 +1,6 @@ { "name": "expo-doctor", - "version": "1.18.7", + "version": "1.18.8", "main": "build/index.js", "description": "Check your Expo project for known issues", "keywords": [ diff --git a/packages/expo-module-template/$package.json b/packages/expo-module-template/$package.json index 9cb7c14e2cd750..33ea677cc27f91 100644 --- a/packages/expo-module-template/$package.json +++ b/packages/expo-module-template/$package.json @@ -32,7 +32,7 @@ "devDependencies": { "@types/react": "~19.1.1", "expo-module-scripts": "^55.0.2", - "expo": "^55.0.1", + "expo": "^55.0.2", "react-native": "0.82.1" }, "peerDependencies": { diff --git a/packages/expo-router/CHANGELOG.md b/packages/expo-router/CHANGELOG.md index 35be720faf92ca..2ee3ff10587424 100644 --- a/packages/expo-router/CHANGELOG.md +++ b/packages/expo-router/CHANGELOG.md @@ -10,6 +10,10 @@ ### 💡 Others +## 55.0.2 — 2026-02-25 + +_This version does not introduce any user-facing changes._ + ## 55.0.1 — 2026-02-25 ### 🎉 New features diff --git a/packages/expo-router/android/build.gradle b/packages/expo-router/android/build.gradle index 9b5044a933f2be..475f46d3f04a8a 100644 --- a/packages/expo-router/android/build.gradle +++ b/packages/expo-router/android/build.gradle @@ -4,13 +4,13 @@ plugins { } group = 'expo.modules.router' -version = '55.0.1' +version = '55.0.2' android { namespace "expo.modules.router" defaultConfig { versionCode 1 - versionName "55.0.1" + versionName "55.0.2" } lintOptions { abortOnError false diff --git a/packages/expo-router/package.json b/packages/expo-router/package.json index caca2b3b94c857..3514308c541271 100644 --- a/packages/expo-router/package.json +++ b/packages/expo-router/package.json @@ -1,6 +1,6 @@ { "name": "expo-router", - "version": "55.0.1", + "version": "55.0.2", "description": "Expo Router is a file-based router for React Native and web applications.", "author": "650 Industries, Inc.", "license": "MIT", diff --git a/packages/expo/CHANGELOG.md b/packages/expo/CHANGELOG.md index f33c1ede5835f9..f666b2c1558614 100644 --- a/packages/expo/CHANGELOG.md +++ b/packages/expo/CHANGELOG.md @@ -10,6 +10,10 @@ ### 💡 Others +## 55.0.2 — 2026-02-25 + +_This version does not introduce any user-facing changes._ + ## 55.0.1 — 2026-02-25 _This version does not introduce any user-facing changes._ diff --git a/packages/expo/android/build.gradle b/packages/expo/android/build.gradle index a952e7a16dfe82..b93cbf4d43cd65 100644 --- a/packages/expo/android/build.gradle +++ b/packages/expo/android/build.gradle @@ -10,7 +10,7 @@ buildscript { } group = 'host.exp.exponent' -version = '55.0.1' +version = '55.0.2' expoModule { // We can't prebuild the module because it depends on the generated files. @@ -21,7 +21,7 @@ android { namespace "expo.core" defaultConfig { versionCode 1 - versionName "55.0.1" + versionName "55.0.2" consumerProguardFiles("proguard-rules.pro") } testOptions { diff --git a/packages/expo/bundledNativeModules.json b/packages/expo/bundledNativeModules.json index 4b5a5137686af6..f280ea877c3206 100644 --- a/packages/expo/bundledNativeModules.json +++ b/packages/expo/bundledNativeModules.json @@ -70,7 +70,7 @@ "expo-notifications": "~55.0.10", "expo-print": "~55.0.8", "expo-live-photo": "~55.0.8", - "expo-router": "55.0.1", + "expo-router": "~55.0.2", "expo-screen-capture": "~55.0.8", "expo-screen-orientation": "~55.0.8", "expo-secure-store": "~55.0.8", diff --git a/packages/expo/package.json b/packages/expo/package.json index 340ce2ff957d1f..4694312298040d 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -1,6 +1,6 @@ { "name": "expo", - "version": "55.0.1", + "version": "55.0.2", "description": "The Expo SDK", "main": "src/Expo.ts", "module": "src/Expo.ts", diff --git a/packages/patch-project/CHANGELOG.md b/packages/patch-project/CHANGELOG.md index e957b60ab4bd8a..8922d4d1c7adac 100644 --- a/packages/patch-project/CHANGELOG.md +++ b/packages/patch-project/CHANGELOG.md @@ -10,6 +10,10 @@ ### 💡 Others +## 55.1.7 — 2026-02-25 + +_This version does not introduce any user-facing changes._ + ## 55.1.6 — 2026-02-25 _This version does not introduce any user-facing changes._ diff --git a/packages/patch-project/package.json b/packages/patch-project/package.json index e09781f8e6bdac..d8568564796d20 100644 --- a/packages/patch-project/package.json +++ b/packages/patch-project/package.json @@ -1,6 +1,6 @@ { "name": "patch-project", - "version": "55.1.6", + "version": "55.1.7", "description": "An Expo config-plugin and tool to support patch-based CNG", "main": "build/withPatchPlugin.js", "types": "build/withPatchPlugin.d.ts", diff --git a/templates/expo-template-bare-minimum/package.json b/templates/expo-template-bare-minimum/package.json index 45b73448e7df9c..d5ff43441f1f14 100644 --- a/templates/expo-template-bare-minimum/package.json +++ b/templates/expo-template-bare-minimum/package.json @@ -2,7 +2,7 @@ "name": "expo-template-bare-minimum", "description": "This bare project template includes a minimal setup for using unimodules with React Native.", "license": "0BSD", - "version": "55.0.13", + "version": "55.0.14", "main": "index.js", "scripts": { "start": "expo start --dev-client", @@ -11,7 +11,7 @@ "web": "expo start --web" }, "dependencies": { - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-status-bar": "~55.0.4", "react": "19.2.0", "react-native": "0.83.2" diff --git a/templates/expo-template-blank-typescript/package.json b/templates/expo-template-blank-typescript/package.json index ce0616079e7254..4cde0fd8430a2d 100644 --- a/templates/expo-template-blank-typescript/package.json +++ b/templates/expo-template-blank-typescript/package.json @@ -2,7 +2,7 @@ "name": "expo-template-blank-typescript", "description": "The Blank project template includes the minimum dependencies to run and an empty root component.", "license": "0BSD", - "version": "55.1.8", + "version": "55.1.9", "main": "index.ts", "scripts": { "start": "expo start", @@ -11,7 +11,7 @@ "web": "expo start --web" }, "dependencies": { - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-status-bar": "~55.0.4", "react": "19.2.0", "react-native": "0.83.2" diff --git a/templates/expo-template-blank/package.json b/templates/expo-template-blank/package.json index 97099b6c5197d5..5f2ddd5bd27cd1 100644 --- a/templates/expo-template-blank/package.json +++ b/templates/expo-template-blank/package.json @@ -2,7 +2,7 @@ "name": "expo-template-blank", "description": "The Blank project template includes the minimum dependencies to run and an empty root component.", "license": "0BSD", - "version": "55.1.8", + "version": "55.1.9", "main": "index.js", "scripts": { "start": "expo start", @@ -11,7 +11,7 @@ "web": "expo start --web" }, "dependencies": { - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-status-bar": "~55.0.4", "react": "19.2.0", "react-native": "0.83.2" diff --git a/templates/expo-template-default/package.json b/templates/expo-template-default/package.json index 851523c5ee69c2..33ca56818b9e10 100644 --- a/templates/expo-template-default/package.json +++ b/templates/expo-template-default/package.json @@ -2,7 +2,7 @@ "name": "expo-template-default", "license": "0BSD", "main": "expo-router/entry", - "version": "55.1.8", + "version": "55.1.9", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", @@ -16,14 +16,14 @@ "@react-navigation/bottom-tabs": "^7.7.3", "@react-navigation/elements": "^2.8.1", "@react-navigation/native": "^7.1.28", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-constants": "~55.0.7", "expo-device": "~55.0.9", "expo-font": "~55.0.4", "expo-glass-effect": "~55.0.7", "expo-image": "~55.0.5", "expo-linking": "~55.0.7", - "expo-router": "~55.0.1", + "expo-router": "~55.0.2", "expo-splash-screen": "~55.0.9", "expo-status-bar": "~55.0.4", "expo-symbols": "~55.0.4", @@ -34,7 +34,7 @@ "react-native": "0.83.2", "react-native-gesture-handler": "~2.30.0", "react-native-worklets": "0.7.2", - "react-native-reanimated": "~4.2.1", + "react-native-reanimated": "4.2.1", "react-native-safe-area-context": "~5.6.2", "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0" diff --git a/templates/expo-template-tabs/package.json b/templates/expo-template-tabs/package.json index 7923a7ce5ed734..a9112d1726b9c2 100644 --- a/templates/expo-template-tabs/package.json +++ b/templates/expo-template-tabs/package.json @@ -3,7 +3,7 @@ "main": "expo-router/entry", "description": "The Tab Navigation project template includes several example screens.", "license": "0BSD", - "version": "55.1.8", + "version": "55.1.9", "scripts": { "start": "expo start", "android": "expo start --android", @@ -13,11 +13,11 @@ "dependencies": { "@expo/vector-icons": "^15.0.2", "@react-navigation/native": "^7.1.28", - "expo": "~55.0.1", + "expo": "~55.0.2", "expo-constants": "~55.0.7", "expo-font": "~55.0.4", "expo-linking": "~55.0.7", - "expo-router": "~55.0.1", + "expo-router": "~55.0.2", "expo-splash-screen": "~55.0.9", "expo-status-bar": "~55.0.4", "expo-web-browser": "~55.0.9", @@ -25,7 +25,7 @@ "react-dom": "19.2.0", "react-native": "0.83.2", "react-native-worklets": "0.7.2", - "react-native-reanimated": "~4.2.1", + "react-native-reanimated": "4.2.1", "react-native-safe-area-context": "~5.6.2", "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0"