Contributions
40 PRs merged across 10 upstream repos. Plus a public patches repo with 54 patches: drop-in for Bun, npm, pnpm, and Yarn, plus source-only ones for CI, docs, and native code. I find the bug, file the upstream PR, and drop the patch into the repo so my projects, and anyone else hitting the same bug, can ship without waiting for the merge to land. When the fix lands in a release, I bump the dep and delete the patch. Every merged PR listed here shipped as a patch first.
Merged PRs
- expo/expo (19 PRs):
- #46556 iOS
accessibilityIdentifiermodifier wrapping SwiftUI’saccessibilityIdentifier(_:). Sets a stable, machine-readable id that UI-testing tools like XCUITest read to locate a view, distinct fromaccessibilityLabelin that it’s not user-visible and exists purely for test targeting. RegistersAccessibilityIdentifierModifierand exportsaccessibilityIdentifier(id). Merged, ships in the next@expo/uirelease - #46540 iOS
dynamicTypeSizemodifier to set or clamp Dynamic Type within a view. A single size pins it,{ min, max }bounds the range with either end optional. Caps how far text grows at the largest accessibility sizes for layout safety while still honoring Dynamic Type, and cascades from<Host>to every descendant. Bounds thetextStylescaling from #46007. Merged, ships in the next@expo/uirelease - #46509 the
fontmodifier dropped Dynamic Type scaling (relativeTo) andweighton concatenated<Text>runs, sofont({ textStyle, weight })scaled standalone but lost both once nested in another<Text>. MadeFontModifier.resolveFont()non-private and routed the concatenation path through it so both resolve the identicalFont. Completes #46007. Merged, ships in the next@expo/uirelease - #46050 closed the fork-safety sweep. Gated 15 more workflows on
github.repository == 'expo/expo'so fork CI stops red-checking nightly RN and test-suite jobs, hourly issue-maintenance crons, the GCP publish path inios-prebuild-external-xcframeworks, and Slack-notify steps that reference org-only webhooks. Coverstest-react-native-nightly,test-suite-nightly,lock,issue-stale,cli,create-expo-app,create-expo-module,fingerprint,sdk,ios-static-frameworks,bare-diffs,native-component-list,test-suite,test-suite-macos, and drops a redundant step-level repo check indevelopment-client-latest-e2e. Finishes what #45782 and #45859 started - #46007 iOS
font({ textStyle })for Dynamic Type, wiringtextStylethrough to SwiftUI’sFont.system(_:design:)andFont.custom(_:size:relativeTo:)so@expo/uitext scales with the user’s preferred content size, the SwiftUI-native path for the Larger Text Accessibility Nutrition Label. All 11Font.TextStylecases, withextraLargeTitleandextraLargeTitle2on iOS 17+. Shipped in56.0.10 - #45872
<Host modifiers={...}>was a silent no-op on iOS.HostPropsextendedCommonViewModifierPropsandHost/index.tsxalready forwardedmodifiersto the native view, but the SwiftHostViewPropsnever declared the field, so every typechecked modifier onHostdid nothing. Adding the field plus one.applyModifiers(...)chain inHostView.bodyrestored the entire registered modifier surface toHostin one shot. Shipped in56.0.10 - #45859 gated
pull_request_target,issues, and label-event workflows ongithub.repository == 'expo/expo'so fork PRs stop red-checking on secret-gated jobs that can’t run. Covers 18 workflows includingcode-review,commentator,docs-pr,issue-triage, andsync-template. Sibling to #45782 - #45782 made five auto-firing scheduled workflows fork-safe. Swapped
../expo/(breaks on forks named anything butexpo) for${{ github.workspace }}and gatedvalidate-npm-owners,check-issues-nightly,publish-canaries, and bothdevelopment-client-e2ematrices on the repo check. Dropped failing checks and 120-minute fork CI burns - #45700
Alertcomponent for@expo/uiwrapping SwiftUI’s iOS 15.alert(_:isPresented:actions:message:), withAlert.Trigger,Alert.Actions, and optionalAlert.Messageslots. MirrorsConfirmationDialog’s shape soisPresentedbindings andButtonactions compose the same way. Fills in the previously-stubbed iOS half. Shipped in56.0.8 - #45403
getPackageByNamedid apackages/<name>/package.jsonlookup, which misses for scoped packages whose dir name differs from the package name (@expo/uilives atpackages/expo-ui/,@expo/app-integrityatpackages/expo-app-integrity/). On a miss,Workspace.getInfoAsyncrecorded emptyworkspacePeerDependenciesfor those packages, soupdateWorkspaceProjectsnever rewroteworkspace:*to the canary version, and the published canary tarballs shippedpeerDependencies.expo: "workspace:*".bun add @expo/ui@canaryerrored withWorkspace dependency "expo" not foundandnpm install @expo/ui@canaryerrored withEUNSUPPORTEDPROTOCOL. Fix keeps the existing path-based fast path and falls back to scanningcachedPackagesbynamefield when the path lookup misses. Same root cause as #44412, different call site - #44652
scrollPositionandidmodifiers (iOS 17+) binding aScrollView’s leading target to JS viauseNativeStateand the worklet.valuewrite path. Readingstate.valuereturns the id of the leading target; writing scrolls to the matching view. The optionalonChangecallback fires on the JS thread when the leading target changes.id(string)marks views as scroll targets and works onScrollView,LazyVStack, andLazyHStack. Built on the worklet infrastructure from #44214 and #44215. Deferred from #43955 per @intergalacticspacehighway - #44548
textContentTypemodifier wrapping SwiftUI’stextContentType(_:)with all 45UITextContentTypevalues. Wires@expo/uiTextFieldandSecureFieldinto iOS keychain autofill for passwords, emails, addresses, credit cards, and OTP codes. Before this,@expo/uitext fields could not participate in iOS autofill at all. Includes#availableguards for the iOS 17+ values (creditCardExpiration,birthdate, etc.) and iOS 17.4+ values (cellularEID,cellularIMEI) - #44547
textInputAutocapitalizationmodifier (iOS 15+) with all fourTextInputAutocapitalizationmodes:never,words,sentences,characters. Before this, the only way to disable auto-capitalization on@expo/uiTextFieldwas forcingkeyboardType="ascii-capable", which changed the keyboard layout entirely. Username and email fields can now behave correctly without that workaround - #43958
PersistentFileLog.readEntriesrace condition where reads bypassed theserialQueuethat guards every write. Caused flakyUpdatesLogReaderTests.PurgeOldLogsfailures inexpo-updatesCI when a read executed before a queued write flushed to disk and returnedentries1.count == 1instead of2. Fix wrapsreadEntriesinserialQueue.syncso reads wait for pending writes. No deadlock risk because all callers are external to the queue - #43955
scrollTargetBehaviorandscrollTargetLayoutmodifiers (iOS 17+) for paging and view-aligned scroll snapping in@expo/uiScrollView. Brings SwiftUI’s snap-paging API to React Native through@expo/uimodifier composition with#availableguards for iOS 17, tvOS 17, and macOS 14 - #43923
defaultScrollAnchorForRolemodifier (iOS 18+) wrapping the two-parameterdefaultScrollAnchor(_:for:)overload. Lets you set independent scroll anchors perScrollAnchorRole(initialOffset,sizeChanges,alignment), so a chat view can anchor to bottom globally but start at top via a per-role override. Also addednullsupport to match Apple’sUnitPoint?signature and the missing@platform macos 14.0+JSDoc to the single-arg version from #43914 - #43914
defaultScrollAnchormodifier (iOS 17+) for controlling where aScrollVieworListstarts. Removes the need forscaleEffect(y: -1)flips, reversed data arrays, and inverted scroll indicator hacks that chat UIs used to need. Reuses the existingUnitPointOptionsenum and falls back to a no-op on iOS < 17 - #43228 per-axis
scaleEffectaccepting{ x, y }in addition tonumber. Backwards-compatible:scaleEffect(0.5)still normalizes to{ x: 0.5, y: 0.5 }in the TS layer before hitting native - #43158
ClipShapeModifierandMaskModifierwere silently renderingRectanglefor any shape other thancircleorroundedRectanglebecause they used a rawStringfield instead of theShapeTypeenum from #40748. Every other shape modifier (BackgroundModifier,ContainerShapeModifier,ContentShapeModifier,GlassEffectModifier) already usedShapeType. Switched both to exhaustiveShapeTypeswitching with nodefaultfallthrough, addedroundedCornerStyleandcornerSizefields, and unblockedcapsuleandellipseinclipShape()andmask()
- #46556 iOS
- get-convex/better-auth (5 PRs):
- #218 four bugs causing stale auth state and incorrect
isAuthenticatedvalues. (1)getCookie()parsed cookies from JSON, which turnedexpiresinto a string. Comparingstring < new Date()coerced the Date to a number and the string toNaN, andNaN < anythingis alwaysfalse, so expired cookies were never filtered out. (2) Cookies persisted after/get-sessionreturnednull, so combined with bug 1, stale credentials shipped indefinitely. (3) Sign-out stored"{}"inlocalCacheNameandJSON.parse("{}")returns truthy{}, breakingif (sessionData)checks. Fix stores"null"soJSON.parse("null")returnsnull. (4)isAuthenticatedwassession !== null, which returnedtruefor{}(from bug 3) andundefinedduring loading edges. Fix usesBoolean(session?.session) - #245 widened the
better-authpeer dep from exact1.4.9to>=1.4.9 <1.5.0after verifying every import path is stable across 1.4.9 through 1.4.18. Explicitly excludes 1.5.0, which movedcreateAuthEndpointandcreateAuthMiddlewarefrombetter-auth/pluginstobetter-auth/api, removed thebetter-auth/adapters/testexport path, and deletedrunAdapterTestentirely - #267 concurrent
fetchAccessTokendedup withuseRef. On page load,sessionIdtransitions fromundefinedto a value, which creates a newfetchAccessTokenreference and triggersConvexProviderWithAuthto callsetAuth()again while the first request is still in-flight. React 18 StrictMode doubles this in dev. Each/convex/tokencall hits the DB for session middleware and runs JWT signing, so N concurrent calls meant N redundant round-trips with only one result used. Fix stores the in-flight promise in auseRefso concurrent callers share it, withforceRefreshToken: truebypassing the guard and.finally()clearing the ref after resolution. Closes #219, likely reduces the action count reported in #186 - #278 removed the dead
react-dompeer dep declaration. Zero imports ofreact-dom,ReactDOM,createRoot,hydrateRoot,flushSync, orcreatePortalacross all 32 files insrc/. None of the exports (/react,/nextjs,/react-start) touch it. The declaration was generating peer dep warnings inbunandpnpmprojects that don’t usereact-dom - #323 migrated
@convex-dev/better-authtobetter-auth1.6.7+, fixing five runtime breaks across the 1.6.x line in one rebase.Where.modefolding (1.6.0):CleanedWhere = Required<Where>forced the new field onto every adapter call, soadapterWhereValidatorand per-table validators threwArgumentValidationErroron bump. Fix acceptsmodein validators, case-foldseq/ne/in/not_in/contains/starts_with/ends_withinfilterByWhere, and excludes insensitive clauses fromfindIndexandpaginatefast-paths since Convex indexes are byte-compared.shouldReturnResponseflip (1.6.0, commit8304f65):to-auth-endpoints.tsdefaults to aResponsewhen context carries aRequest, so internal endpoint calls from cross-domain hooks returned aResponseinstead of a parsed object, JWT cookies got the literal string"undefined", andsetSessionCookiecrashed. Fix passesasResponse: falseat all 7 internal call sites with regression tests that pre-set the flags totrueso dropping the override fails the assertion.twoFactor.verified(1.6.2, #8711): new schema column the Convex validator rejected.parseSetCookieHeader: deleted the 34-line local copy incross-domain/client.tsthat split on", "and shatteredExpires=Wed, 21 Oct 2015 07:28:00 GMTinto four garbage cookies, re-exported frombetter-auth/cookies../instrumentation(1.6.6, #9111): peer floor raised to 1.6.7 where #9281 routes the dynamicimport("@opentelemetry/api")to a noop onbrowserandedgeconditions, fixing Convex V8 isolate’s synchronous bare-specifier rejection. Shipped in@convex-dev/better-auth@0.12.0
- #218 four bugs causing stale auth state and incorrect
- shadcn-ui/ui (5 PRs):
- #10396 added the TanStack Start dark mode guide to the official shadcn docs, the fifth framework-specific guide after Next.js, Vite, Astro, and Remix. The canonical pattern was scattered across Discord threads and three stale PRs with different tradeoffs: #7173 (cookies, no system mode), #7490 (cookies, conditional
ScriptOnce), and #9096 (wrappedtanstack-theme-kitas a runtime dep). Pattern:ScriptOncefrom@tanstack/react-routerfor the pre-hydration inline script, a React context for post-hydration state,suppressHydrationWarningon<html>,document.documentElement.style.colorSchemeso native UI respects the theme, and aprefers-color-schemelistener for system mode. In review, @shadcn refactored the inline script string into agetThemeScript(storageKey, defaultTheme)function so custom provider props reach the pre-hydration pass, extracted the class-swap into anapplyThemehelper, and added amountedgate so the inline script’s work isn’t overwritten on first mount - #10369
notFoundComponenton the Start root route in thestart-appandstart-monorepotemplates. Silences the TanStack Router warning that fires on first load from phantom requests hitting/favicon.icoand Chrome DevTools’/.well-known/appspecific/com.chrome.devtools.jsonwhen neithernotFoundComponentnordefaultNotFoundComponentis configured. JSX shape matches the existing 404ErrorBoundarypattern fromtemplates/react-router-appandtemplates/react-router-monorepo(samecontainer mx-auto p-4 pt-16wrapper, same “404” heading and “The requested page could not be found.” copy) so the ten-template suite stays consistent - #10337 fixed
llms.txt404s and backfilled missing routes so LLM crawlers can index the full docs site - #9484 raw
<ComponentsList />tag leaking into copy-to-markdown output on component pages - #9331 registered the
@ramonclaudio-coderabbitshadcn registry in the official open source directory after #8892 asked for it. Adds entries toapps/v4/public/r/registries.jsonandapps/v4/registry/directory.jsonso the registry is discoverable through the shadcn CLI. The registry itself ships a framework-agnostic CodeRabbit API client, pluggable storage adapters (LocalStorage, Convex, Supabase, PostgreSQL, MySQL), and React components for generating developer activity reports
- #10396 added the TanStack Start dark mode guide to the official shadcn docs, the fifth framework-specific guide after Next.js, Vite, Astro, and Remix. The canonical pattern was scattered across Discord threads and three stale PRs with different tradeoffs: #7173 (cookies, no system mode), #7490 (cookies, conditional
- better-auth/better-auth (3 PRs):
- #9281 serve a noop
./instrumentationvia conditional exports forbrowserand edge runtimes, matching the shape./async_hooksalready uses. The dynamicimport("@opentelemetry/api")inpackages/core/src/instrumentation/api.tsthrew synchronously on runtimes like Convex’s V8 isolate (bare specifiers rejected at resolve time viadeno_core::resolve_import), so the.catch()ingetOpenTelemetryAPInever ran and everywithSpancall throughto-auth-endpoints.tsandwith-hooks.tssurfaced an uncaught error. The breaking pattern landed in#9111and shipped in v1.6.6.@opentelemetry/apiitself ships a noop proxy when no SDK is registered, so this is about dynamic-import-probe portability, not OTel runtime support. Unblocks the 1.6 migration for@convex-dev/better-authconsumers - #9087 add
/change-passwordand/revoke-other-sessionsto theatomListenersmatcher so$sessionSignalfires after session-rotating endpoints. Without this, callers likeuseSession()kept returning stale session data after password changes because the client never re-fetched. Companion to get-convex/better-auth#329 which invalidates the Convex adapter’s cached JWT on the same events - #9072 incorrect
operationIdin the password reset callback endpoint, plusforgettoforgotcleanup across demo apps and tests
- #9281 serve a noop
- withastro/compiler-rs (2 PRs):
- #25 real fix for the
@astrojs/compiler-rsGLIBC_2.35issue. #22 added-xto the linux-gnu builds hoping zigbuild would pin glibc, but zigbuild without an explicit suffix falls back to zig’s per-arch baseline (GLIBC_2.35on x86_64,GLIBC_2.30on aarch64 for zig 0.15), so the shipped 0.1.7 binary still couldn’t load on Vercel (glibc 2.34), Amazon Linux 2023, AWS Lambda, RHEL/CentOS 7, or Debian 10. Switched both gnu targets to--use-napi-cross, which downloads@napi-rs/cross-toolchainwith a sysroot pinned to glibc 2.17. Matches the pattern used byoxc,@swc/core,@napi-rs/canvas,lightningcss, and the official@napi-rs/package-template. Verified on a fork CI run plus a Vercel preview deploy withexperimental.rustCompiler: true, bothobjdump -TshowingGLIBC_2.16max on x64 andGLIBC_2.17on arm64. Shipped in@astrojs/compiler-rs@0.1.8 - #22 first-attempt glibc compat fix, added
-xtox86_64-unknown-linux-gnu. Turned out to be insufficient, superseded by #25
- #25 real fix for the
- napi-rs/napi-rs (1 PR): #3189 cross-compile regression in the v3 CLI rewrite. When
--cross-compile/-xwas passed for a linux or darwin target,pickBinary()incli/src/api/build.tsskippedcargo-zigbuildif host platform, arch, and abi matched target, logged a warning, then silently fell through tocargo build. The whole point of--cross-compileon a native build is to pin a lower glibc via zig’s linker. Without it, buildingx86_64-unknown-linux-gnuonubuntu-latest(glibc 2.39) produced binaries incompatible with glibc < 2.35 systems like Amazon Linux 2023 (glibc 2.34) and Vercel’s build container. v2 had this fix in #1432 (resolving #1430) but it wasn’t carried over during the v3 rewrite in #1492. Fix removes the platform-match conditions in theelsebranch ofpickBinary()so--cross-compilealways usescargo-zigbuildfor non-Windows targets - oven-sh/bun (1 PR): #21855 added the
decompressproperty to theBunFetchRequestInitinterface with JSDoc documentation. The option already worked at runtime in Bun’sfetch(), but TypeScript users had to@ts-ignoreit on every call to disable response decompression. Now it’s a first-class typed option, no escape hatch required - fuma-nama/fumadocs (2 PRs):
- #2092 fixed the TanStack Start template in
create-fumadocs-app. Wired thevite-reactplugin with the requiredcustomViteReactPlugin: trueflag, configured a customNotFoundcomponent for TanStack Router, and bumped deps to current versions. Resolved four issues at once: TanStack Startvite-reactplugin warning, missing custom 404 component warning, module resolution errors during client-side navigation, and React hydration errors caused byuseMemonull references that flashed errors mid-route-change - #2095 prettier formatting fix that unblocked the changesets release PR #2093 for
create-fumadocs-app@15.7.0. The release PR was stuck on a formatting check, so I ran the formatter and shipped the diff so the release could go out
- #2092 fixed the TanStack Start template in
- rorkai/App-Store-Connect-CLI (1 PR): #784 Mac App Store screenshot support for the
ascCLI. New--provider macosgrabs the frontmost window of a running macOS app by bundle ID usingscreencapture -l <windowID>, where the window ID comes from a Swift one-liner piped toswift -viaCGWindowListCopyWindowInfo, without cgo or extra binaries. New--device macrenders to the 2880x1800APP_DESKTOPcanvas without a device bezel, with optional title, subtitle, and background color overlays. Also fixedASC_TIMEOUTbeing silently ignored forscreenshots captureandscreenshots frame, both now useContextWithTimeout - TanStack/db (1 PR): #17 corrected the stale README link to the example todo app, repointing it at
examples/react/todo. Tiny fix, but it was the first thing I clicked when I landed on the repo and it 404’d. Was PR #17 in the repo, early days
Patches
Drop-in for Bun, npm, pnpm, and Yarn. Source-only patches for CI, docs, and native code apply with git apply.
Open
PRs still awaiting upstream merge.
@expo/ui56.0.15: Add the iOSaccessibilityHiddenmodifier wrapping SwiftUI’saccessibilityHidden(_:), hiding decorative views (hero icons, imagery already described by adjacent text) from VoiceOver traversal. RegistersAccessibilityHiddenModifierand exportsaccessibilityHidden(hidden?), defaulting totrue. expo/expo#46579react-native0.85.3: Set:always_out_of_dateonhermes-engine.podspec’sReplace Hermesscript phase so Xcode stops warning that it runs every build without declaring outputs. Matches the guard already on the siblingReplace Xphases, while the phase still swaps the prebuilt Hermes binary per$CONFIGURATION. facebook/react-native#56912hermes: Cherry-pick18a9634659onto the250829098.0.0-stablebranch RN 0.85 ships.genObjectExprpassednullptras the home object for object-literal getters and setters, sosuper.xinside an accessor compiled against a null home object and SIGSEGV’dhermescat compile time. Routes accessors through the samecapturedObjpath regular methods already use. Source fix for one of the Hermes V1 codegen bugsbabel-preset-expoworks around, root cause facebook/hermes#1761. facebook/hermes#2045hermes: Cherry-pick1e94fbe0ebonto250829098.0.0-stable. Afinallyblock emits its body twice, and on the second pass legacy class compilation built fresh internal Variables while cached functions reached viafindCompiledEntitystill pointed at the originals, miscompiling anyclassdeclared infinally. Caches them in aLegacyClassVarsstruct keyed by the class AST node and emits private-brand stores unconditionally. Source fix for the class-in-finally half of facebook/hermes#1761. facebook/hermes#2046hermes: Swap the hardcodedhermessource dir for${{ github.event.repository.name }}in thetest-linux-armv7job’scmake -Sandtest_runner.pypaths. The job runsactions/checkout@v1withoutpath:(v4 breaks in the arm32 container), so the checkout dir takes the repo name and the job fails on any fork not namedhermes. Unchanged upstream. facebook/hermes#2047bun1.3.14: Fixbun add X@versionbeing silently ignored whenXis a same-namepeerDependency, leavingbun.lockandnode_modulespinned to the peer’s first-resolved version. The order-dependent peer early-match inget_or_put_resolved_packageis dropped so peers flow throughfind_best_version, with dedup moved toTree::hoist_dependencywhere placement is deterministic. oven-sh/bun#30855@convex-dev/better-auth0.12.2: Wrap thefetchAccessTokenbody in an explicitnew Promise(executor)souseConvexAuth().isAuthenticatedflips after sign-in on Hermes V1. The async arrow with non-simple params hit a Hermes native bug (facebook/hermes#1761) that the SDK 56 canary exposed when it dropped@babel/plugin-transform-async-to-generator, leaving the Convex auth bridge paused even after the JWT landed. get-convex/better-auth#368@convex-dev/better-auth0.12.2: Clear the cached JWT whensessionIdchanges, not just on logout, so the firstfetchAccessTokenafter a session rotation stops returning a token for the deleted session.cachedTokenis backed by a ref the fetcher reads inline, with a promise-identity guard blocking a late staletoken()fetch from clobbering a fresh value. get-convex/better-auth#329better-auth1.6.11: StopchangePassword({ revokeOtherSessions: true })from rotating the caller’s own session, which left cached JWTs pointing at a deleted session id and broke therevokeOtherSessionscontract. AddsinternalAdapter.deleteOtherSessions(userId, exceptToken)and routes both/change-passwordand/revoke-other-sessionsthrough it. better-auth/better-auth#9345@hugeicons/react1.1.6: Add an ambient declaration for@hugeicons/core-free-icons/*subpath imports typed asIconSvgElement, auto-loaded via a triple-slash reference insrc/index.ts. The package advertises"./*"exports but ships only the barrelindex.d.ts, so subpaths resolve at runtime yet fail typechecking undernode16,nodenext, andbundler, forcing the 6.2 MB barrel instead of the 33 KB you use. hugeicons/react#5shadcn4.7.0: Strip C0 control characters (0x00-0x1F) and DEL (0x7F) frompromptstext input via a wrapper every command routes through. On macOS,Cmd+Deleteto clear the default name sendsCtrl+U(\x15), whichpromptsinserts as a literal byte and turns into names like\x15my-app. shadcn-ui/ui#10364bun1.3.13: Switch thelabelsinput inupdate-root-certs.ymlfrom a YAML sequence to the pipe-delimited stringpeter-evans/create-pull-requestexpects. The sequence form made GitHub Actions reject the workflow withA sequence was not expectedon every push. oven-sh/bun#27086
Merged, awaiting release
PR merged upstream, patch still live until the fix ships in a published release.
@expo/ui56.0.15: Add the iOSaccessibilityIdentifiermodifier wrapping SwiftUI’saccessibilityIdentifier(_:), a stable machine-readable id that UI-testing tools like XCUITest read to locate a view. Not user-visible, purely for test targeting, distinct fromaccessibilityLabel. expo/expo#46556@expo/ui56.0.15: Add the SwiftUIdynamicTypeSizemodifier to set or clamp Dynamic Type within a view, a single size or a{ min, max }range, cascading from<Host>to bound how far text scales at the largest accessibility sizes. expo/expo#46540@expo/ui56.0.15: Resolve thefontmodifier on the Text-concatenation path so concatenated<Text>runs keeprelativeTo(Dynamic Type) andweight.FontModifier.resolveFont()is now shared by the view and concatenation paths instead of a fixed-sizeFont.customthat dropped both. expo/expo#46509
Dropped
PR merged, patch deleted, dep bumped.
expofork CI:- Make five auto-firing scheduled workflows fork-safe by swapping
../expo/paths for${{ github.workspace }}and gating org-maintenance jobs behindif: github.repository == 'expo/expo'. The relative path only resolved when the checkout dir was namedexpo, so differently named forks hitNo such file or directory, while the gated jobs read secrets likeNPM_TOKEN_READ_ONLYthat forks cannot see. #45782 - Gate the
pull_request_target,issues, and label workflows behind the same repo check so they skip cleanly on forks instead of sitting red. Coverscode-review,commentator,docs, theissue-triagejobs, and the labelers, each reading an org-only secret or bot token. #45859 - Gate the remaining nightly artifact tests, hourly issue crons, the GCP publish path in
ios-prebuild-external-xcframeworks, and Slack-notify steps to finish the sweep.github.repositoryis a built-in context, so every guard is true upstream and skips the job or step on forks. #46050
- Make five auto-firing scheduled workflows fork-safe by swapping
@expo/ui56.0.9->56.0.10: Add an optionaltextStylefield to thefontmodifier so text scales with iOS Dynamic Type, accepting the 11Font.TextStylecases. It routes throughFont.system(_:design:)andFont.custom(_:size:relativeTo:), the SwiftUI-native path for Apple’s Larger Text criteria, while fixed-sizefonts stay unchanged. #46007@expo/ui56.0.8->56.0.10: Declare themodifiersfield on Swift’sHostViewPropsand chain.applyModifiers(...)inHostView.bodyso<Host modifiers={...}>stops getting dropped on iOS. The TS side already forwarded the prop, so one field plus one chain routesHostthrough the sameViewModifierRegistrydispatch asUIBaseView, restoring the full registered modifier set. #45872@expo/ui56.0.0-canary-20260506-03817f5->56.0.8: Add anAlertcomponent for@expo/ui/swift-uiwrapping iOS 15’s.alert(_:isPresented:actions:message:)with aTrigger/Actions/Messageslot model mirroringConfirmationDialog. Two-wayisPresentedbinding runs throughEventDispatcherwith aprops.isPresented != newValueguard so SwiftUI’s auto-dismiss fires the change exactly once. #45700expocanary-20260506-964f25d: Resolve scoped packages by theirnamefield when thepackages/<name>path lookup misses, so@expo/ui(atpackages/expo-ui/) and@expo/app-integrityget theirworkspacePeerDependenciesrecorded. The miss leftpeerDependencies.exposhipping asworkspace:*in canary tarballs and breakingbun installandnpm install, the same root cause as #44412 at a call site its fix never reached. #45403better-auth1.6.2->1.6.5: Add/change-passwordand/revoke-other-sessionsto the defaultatomListenersmatcher./change-passwordwithrevokeOtherSessions: truerotates the caller’s session but was missing from the matcher, so$sessionSignalnever flipped anduseSession()served the stale session until the next focus, poll, or reload. #9087@expo/ui56.0.0-canary-20260212-4f61309->56.0.0-canary-20260305-5163746:- Switch
ClipShapeModifierandMaskModifierfrom a rawStringfield to theShapeTypeenum with an exhaustive switch over all five cases. Both silently fell through toRectangle()forcapsuleandellipse, soclipShape("capsule")rendered a rectangle with no error afterShapeTypelanded in #40748. #43158 - Let
scaleEffecttake{ x, y }for per-axis scaling, not just a single number. The TS layer normalizes a bare number to{ x, y }so existingscaleEffect(0.5)calls keep working, and the Swift vars pass straight tocontent.scaleEffect(x:y:), which unlocks a vertically flipped invertedList. #43228
- Switch
@expo/ui56.0.0-canary-20260212-4f61309->56.0.0-canary-20260401-5e87ef7:- Add a
defaultScrollAnchormodifier wrapping SwiftUI’s.defaultScrollAnchor(_:)on iOS 17+. AScrollViewcan start pinned tobottomwithout ascaleEffect(y: -1)flip or reversed data, reusing the existingUnitPointOptionsenum and falling back to a no-op below iOS 17. #43914 - Add a
defaultScrollAnchorForRolemodifier wrapping the two-parameter.defaultScrollAnchor(_:for:)on iOS 18+, with aScrollAnchorRoleofinitialOffset,sizeChanges, oralignment. Each role anchor is set independently andnullopts out, matching Apple’sUnitPoint?signature, which also addsnullsupport back todefaultScrollAnchor. #43923
- Add a
@expo/ui56.0.0-canary-20260212-4f61309->56.0.0-canary-20260409-6fc2991:- Add
scrollTargetBehaviorforpagingorviewAlignedsnapping andscrollTargetLayoutto mark the snap target, both guarded for iOS 17+.scrollTargetLayoutmoves from a stack prop to a modifier to match SwiftUI, while scroll position state and callbacks stay deferred pending worklet support in #44214. #43955 - Add a
textInputAutocapitalizationmodifier on iOS 15+ withnever,words,sentences, andcharactersmodes. Before this there was no way to disable autocapitalization onTextFieldshort ofkeyboardType="ascii-capable", which also swaps the keyboard layout. #44547 - Add a
textContentTypemodifier on iOS 13+ mapping all 45UITextContentTypevalues so fields join keychain autofill for passwords, emails, addresses, and OTP codes. The iOS 17+ and 17.4+ values carry#availableguards, since without the modifier aTextFieldcannot participate in autofill at all. #44548
- Add
expo-modules-core56.0.0-canary-20260212-4f61309->56.0.0-canary-20260402-87c5ce2: WrapPersistentFileLog.readEntriesinserialQueue.syncso reads wait for queued writes instead of bypassing the serial queue that guards every write. The race madeUpdatesLogReaderTests.PurgeOldLogsflaky when a read ran before a pending write hit disk, with no deadlock risk since all callers sit outside the queue. #43958@convex-dev/better-auth0.10.10->0.10.11:- Fix four bugs that left stale credentials in storage and reported wrong
isAuthenticatedvalues after a session expired.getCookie()compared aJSON.parse’dexpiresstring against aDate(alwaysNaN), sign-out stored truthy"{}"instead of"null", andisAuthenticatednow readsBoolean(session?.session). #218 - Widen the
better-authpeer range from exact1.4.9to>=1.4.9 <1.5.0, covering the whole 1.4.x line. Caps below1.5.0, which movescreateAuthEndpointandcreateAuthMiddlewareout ofbetter-auth/plugins, drops theadapters/testpath, and deletesrunAdapterTest. #245
- Fix four bugs that left stale credentials in storage and reported wrong
@convex-dev/better-auth0.10.11->0.10.12: Share one in-flighttoken()promise across concurrentfetchAccessTokencallers instead of firing a separate/convex/tokenrequest for each. ApendingTokenRefholds the promise and clears in.finally(), so thesessionIdtransition and React 18 StrictMode double-invoke no longer trigger N redundant session-middleware and JWT-signing round-trips. #267@convex-dev/better-auth0.10.12->0.10.13: Dropreact-domfrompeerDependencies. No file undersrc/importsreact-dom,createRoot,hydrateRoot,flushSync, orcreatePortal, so the dead entry only produced peer warnings inbunandpnpmprojects that never pull it in. #278@convex-dev/better-auth0.11.5->0.12.0: Raise thebetter-authpeer floor to>=1.6.7 <1.7.0and fix five runtime breaks the 1.6 line introduces. Adapter validators accept theWhere.modefield, internal endpoint calls passasResponse: falseso tokens stop becoming the string"undefined", thetwoFactortable gainsverified,parseSetCookieHeaderdelegates tobetter-auth/cookies, and./instrumentationresolves to a noop Convex’s V8 isolate can load. #323bun1.2.20->1.2.21: Add thedecompressproperty to theBunFetchRequestInitinterface sodecompress: falsetype-checks without a@ts-ignore. The option already worked at runtime, so this only closes the gap between behavior and the published types. #21855create-fumadocs-app15.6.4->15.6.5:- Wire
@vitejs/plugin-reactinto thetanstack-starttemplatevite.config.tsand setdefaultNotFoundComponentto a newNotFoundcomponent. Clears the vite-react plugin and missing-404 warnings plus the hydration and module-resolution errors that flashed during client-side navigation. #2092 - Reflow the
NotFound.tsxparagraph text to satisfy Prettier line length. The unformatted file failed the format check and blocked the changesets release PR #2093. #2095
- Wire