NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #3778 most downloaded on npm
The core of Expo Modules architecture
Last release today
03 Oct 2026
Ships on a steady schedule
a new release about every 9 days
Most releases are documented
notes for 48 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
5 years old
456 releases · first in 2021
One column per quarter.
[Internal][Android] expoPublish now formats the updated expo-module.config.json with oxfmt instead of prettier. (#47438 by @hassankhan)
expoPublish now formats the updated expo-module.config.json with oxfmt instead of prettier. (#47438 by @hassankhan)decodableKinds to JavaScriptDecodable: the kinds of JavaScript value (JavaScriptValueKinds) that decode can accept, so code that picks between several types can skip the ones that can't match. (#50905 by @tsapeta)JavaScriptValue.withUnownedValue(in:_:), and give the owning JavaScriptDecodable.decode a default that borrows the value and decodes it through the JavaScriptUnownedValue overload, so a conformer can implement only that one. Arrays, dictionaries, dates, records and enums now decode unowned values without copying them first. (#50960 by @tsapeta)aria-*, id and tabIndex props such as aria-hidden and aria-label (#50782). (#50959 by @alanjhughes)release() throwing on a shared object whose JS object is frozen, for example an ImageRef passed as a view prop in development (#50962). (#50970 by @tsapeta)Bump precompiled artifacts due to ABI breakage in expo-modules-jsi@58.0.6. (#50881 by @kitten)
@Record now accepts properties that hold free-form Any values, such as [String: Any]? or [Any]. (#50660 by @tsapeta)Lay out RNHostView hosted content at the size SwiftUI or Compose gives it on an axis that matchContents does not match. (#50674 by @intergalacticspace
RNHostView hosted content at the size SwiftUI or Compose gives it on an axis that matchContents does not match. (#50674 by @intergalacticspacehighway)Force-bump all packages, due to migration to changesets. (#50762 by @kitten)
expo-modules-macros, the new name of the @expo/expo-modules-macros-plugin package. (#50680 by @tsapeta)The app context has been lost) when an Expo view mounts during a reload. (#50721 by @tsapeta)[Android] Throw a JavaScript error instead of aborting when returning a shared object whose JavaScript instance is no longer available. (#50667 by @lu
Fixed listeners removed with subscription.remove() never being garbage-collected, together with their emitter and everything their closure references,
subscription.remove() never being garbage-collected, together with their emitter and everything their closure references, when the closure can reach the subscription (as in useEvent, useEventListener or a useEffect that returns () => subscription.remove()). (#50603 by @gkueny)Exception reporting undefined reason to JavaScript instead of the description it was created with, which also affected every promise.reject(code, description) call. (#50215 by @Maher-Reven)Added Platform.isQuest to detect Meta Quest devices from JavaScript. (#50283 by @behenate)
Cannot use shared object that was already released, and sharedObjectDidRelease being called in the middle of a pending call, when the garbage collector took the JS object of a shared object receiver or argument before the call finished. (#50513 by @lukmccall)nil record fields being omitted instead of returned as null when a function's return type is an optional record. (#50560 by @wenszel)[iOS] Added SceneGeometry.anchorPopover(ofrect:) so modules anchor popovers by presentation style instead of the iPad idiom, which regular-width phone
SceneGeometry.anchorPopover(of:to:rect:) so modules anchor popovers by presentation style instead of the iPad idiom, which regular-width phones such as iPhone Duo need. (#50433 by @alanjhughes)[iOS] Added EmbeddedFingerprint, which reads the fingerprint a debug build embedded, with EmbeddedFingerprint.CheckProtocol carrying the literals of t
EmbeddedFingerprint, which reads the fingerprint a debug build embedded, with EmbeddedFingerprint.CheckProtocol carrying the literals of the fingerprint-check exchange. (#49494 by @vonovak)NoSuchFieldError in minified release builds. (#50502 by @dhalenok, #50510 by @intergalacticspacehighway)ComposeView's view id with a tag for its rememberSaveable namespace, fixing a crash on react-native-screens tab switch and touches inside a Host reaching the wrong React Native view. (#49964 by @b2x-software, #50299 by @intergalacticspacehighway)reactTag, which the virtual view did not declare. (#50342 by @gabrieldonadel)accessibilityViewIsModal, which UIKit only implements for the menu container while its accessibility bundle is loaded. (#48765 by @ayyoub-coder, #49916 by @intergalacticspacehighway)@expo/expo-modules-macros-plugin to 0.12.0. (#50286 by @tsapeta)libraryVersion check so the archive stays valid across patch releases, and add the expo.core.buildFromSource Gradle property to opt out. (#50452 by @lukmccall)_This version does not introduce any user-facing changes._
This version does not introduce any user-facing changes.
[Android] Compile expo-module-gradle-plugin against Android Gradle Plugin 9.2.1 and drop the Android Gradle Plugin 8 compatibility code. (#50114 by @l
expo-module-gradle-plugin against Android Gradle Plugin 9.2.1 and drop the Android Gradle Plugin 8 compatibility code. (#50114 by @lukmccall)ArrayBuffers and NativeArrayBuffers being copied instead of shared when passed back from JS on Hermes V1. (#50132 by @lukmccall)[iOS] Added the @Union macro that turns an enum whose cases each carry one associated value into a typed union (A | B in TypeScript), usable as a @JS
@Union macro that turns an enum whose cases each carry one associated value into a typed union (A | B in TypeScript), usable as a @JS argument or return value. (#50037 by @tsapeta).concurrent option to @JS (@JS(.concurrent)), which runs the body of an async function off the JavaScript thread. (#50037 by @tsapeta)[Android] Removed the deprecated AppContext.hostingRuntimeContext property. Use AppContext.runtime instead. (#46964 by @wenszel)
AppContext.hostingRuntimeContext property. Use AppContext.runtime instead. (#46964 by @wenszel)AppContext.errorManager property. Use AppContext.jsLogger instead. (#46964 by @wenszel)ArrayBuffer interface with a concrete class, so NativeArrayBuffer and JavaScriptArrayBuffer no longer share a common ArrayBuffer supertype. (#47106 by @barthap)ConverterContext. (#47850 by @jakex7)EXUtilities.screenScale, which cached the main screen's scale for the process lifetime. Read the scale from the view's trait collection instead. (#48528 by @alanjhughes)UIColor, UIGestureRecognizer and UITextContentType to the AppKit compatibility aliases in Platform.swift. (#50110 by @gabrieldonadel)ExpoSwiftUI.HostingViewAware, an opt-in protocol for view props that receive the view hosting their SwiftUI view, so a view can resolve its own window instead of a process-global one. (#50110 by @gabrieldonadel)loadImageForManipulationFromURL overload to ImageLoaderInterface that decodes the image within the given maxWidth/maxHeight bounds. (#47877 by @jiunshinn)useReleasingSharedObjectWithLifecycle hook. (#46494 by @behenate)ArrayBuffer as the preferred safe native module argument and return type, and deprecated NativeArrayBuffer in favor of it. (#47106 by @barthap)OnCreate, OnDestroy, OnStartObserving and OnStopObserving DSL components: didCreate, willDestroy, didStartListening and didStopListening. (#47542 by @tsapeta)PlatformColor as Color. (#47632 by @jakex7)ArrayBuffer.withJSBytes for safe scoped access to underlying bytes from any thread. (#47261 by @barthap)getNativeRef() to views created with requireNativeViewManager, which returns the underlying host component. (#48788 by @intergalacticspacehighway)ViewProps and ShadowNodeProxy now store their objectWillChange publisher instead of resolving it through Combine's global observable-object table on every access. (#49528 by @wielski)touchStart, onPressIn and onPressOut to the React Native view underneath it. React Native's touch handler is now told to skip that tap before UIKit delivers it, instead of being cancelled afterwards. (#48419 by @nahooni0511, #49775 by @intergalacticspacehighway)registerWebModule as returning an instance of the module class rather than the class itself, matching what it returns at runtime. (#49197 by @dennytosp)BadParcelableException at startup when an activity-result launch was interrupted. DataPersistor read the persisted Bundle with no ClassLoader, so the boot ClassLoader could not resolve androidx.activity.result.ActivityResult. (#49836 by @expo-bot)matchContents RNHostView and the matchContents host around it feeding each other's size back and forth, which grew the layout on every pass. (#49483 by @intergalacticspacehighway)ExpoFabricView.updateProps already worked for UIKit views. (#48426 by @nishan)matchContents hosts sometimes being laid out at a stale size. Regression from #48059. (#49211 by @intergalacticspacehighway)matchContents and Yoga persistently disagree on the content size, e.g. with the Button Shapes accessibility setting enabled. Synchronous size commits are now budgeted per run-loop turn; over-budget updates are coalesced on the view and committed asynchronously on the next turn, and no-op size updates no longer dirty the layout. (#48058, #48059 by @focux)ExpoModulesProvider lookup missing the generated class when the app name starts with a digit, which registered no native modules and left release builds on a blank screen. (#48793 by @expo-bot)EXC_BAD_ACCESS when encoding native Date values to JavaScript. (#48239, #48240 by @samuelcorsan)createAsyncFunction from expo-modules-jsi again, instead of wiring the promise themselves. This also restores rejecting the returned promise (rather than throwing synchronously) when the app context is lost or argument decoding fails. (#47755 by @tsapeta)android.graphics.Color arguments and props on Android below API 26 by adding a ColorCompat wrapper, since the class-based Color API (Color.valueOf and the float accessors) only exists on API 26 and above. PlatformColor values now resolve below API 26 too, via React Native's ARGB-int color path. (#47546 by @anasvemmully) (#47575 by @intergalacticspacehighway)Record arguments crashing with a NullPointerException in R8-optimized release builds when converted through the reflection fallback path. (#46852 by @lukmccall)Record marker interface so its consumer ProGuard rule keeps matching after R8 optimization removes empty marker interfaces. (#46852 by @lukmccall)Host double-composing children. (#46282 by @sadbytes) (#46304 by @nishan)EventEmitter re-export global type indirection (#46719 by @kitten)currentViewController() so it keeps working with multiple scenes, and expose Utilities.keyWindow() for modules to reuse. (#46956 by @alanjhughes)Convertible value that keeps the default convertResult implementation, such as CMTime. The value now converts to undefined and logs a warning. (#48266 by @tsapeta)ActivityResultLauncher.launch() throwing IllegalStateException: Attempting to launch an unregistered ActivityResultLauncher after the Activity is recreated, by registering the launcher again against the live Activity. (#49634 by @idoyana)@expo/expo-modules-macros-plugin to 0.8.0, which emits the two-phase async @JS bindings. (#47755 by @tsapeta)expo-module-gradle-plugin compatible with Android Gradle Plugin 9. (#46769 by @lukmccall)getModule(implementing:) into a public function (#47337 by @Ubax)SceneGeometry for reading bounds, safe area, display scale and interface orientation from the scene a view belongs to. (#48168 by @alanjhughes)SceneGeometry.foregroundScene(), which returns nil when no scene is on screen so callers can avoid presenting UI into a background scene. (#48318 by @alanjhughes)executeSync to up-to-date runSync. runSync is available since 0.7.0. (#48691 by @tjzel)ExpoModulesProviderModuleName lookup key for ExpoModulesProvider class. (#49539 by @kudo)Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
[iOS] Fixed SwiftUI view mounting blocking the main thread: ViewProps and ShadowNodeProxy now store their objectWillChange publisher instead of resolv
ViewProps and ShadowNodeProxy now store their objectWillChange publisher instead of resolving it through Combine's global observable-object table on every access. (#49528 by @wielski)RNHostView with matchContents whose content is laid out more than once, for example a nested host or a Reanimated node. The hosted shadow node could be released before replaceChild finished reading it. (#50456 by @expo-bot)NoSuchFieldError in minified release builds. (#50502 by @dhalenok, #50510 by @intergalacticspacehighway)ComposeView's view id with a tag for its rememberSaveable namespace, fixing a crash on react-native-screens tab switch and touches inside a Host reaching the wrong React Native view. (#49964 by @b2x-software, #50299 by @intergalacticspacehighway)accessibilityViewIsModal, which UIKit only implements for the menu container while its accessibility bundle is loaded. (#48765 by @ayyoub-coder, #49916 by @intergalacticspacehighway)[Android] Fixed BadParcelableException at startup when an activity-result launch was interrupted. DataPersistor read the persisted Bundle with no Clas
[iOS] Fixed the tap that closes a SwiftUI menu still sending touchStart, onPressIn and onPressOut to the React Native view underneath it. React Native
touchStart, onPressIn and onPressOut to the React Native view underneath it. React Native's touch handler is now told to skip that tap before UIKit delivers it, instead of being cancelled afterwards. (#48419 by @nahooni0511, #49775 by @intergalacticspacehighway)_This version does not introduce any user-facing changes._
This version does not introduce any user-facing changes.
Migrated from deprecated react-native-worklets WorkletRuntime API executeSync to up-to-date runSync. runSync is available since 0.7.0. (#48691 by @tjz…
matchContents RNHostView and the matchContents host around it feeding each other's size back and forth, which grew the layout on every pass. (#49483 by @intergalacticspacehighway)ExpoFabricView.updateProps already worked for UIKit views. (#48426 by @nishan)Added getNativeRef() to views created with requireNativeViewManager, which returns the underlying host component. (#48788 by @intergalacticspacehighwa
getNativeRef() to views created with requireNativeViewManager, which returns the underlying host component. (#48788 by @intergalacticspacehighway)[iOS] Fixed matchContents hosts sometimes being laid out at a stale size. Regression from #48059. (#49211 by @intergalacticspacehighway)
matchContents hosts sometimes being laid out at a stale size. Regression from #48059. (#49211 by @intergalacticspacehighway)[iOS] Fixed an infinite main-thread layout loop (frozen UI, watchdog kill on backgrounding) when a SwiftUI host with matchContents and Yoga persistent
matchContents and Yoga persistently disagree on the content size, e.g. with the Button Shapes accessibility setting enabled. Synchronous size commits are now budgeted per run-loop turn; over-budget updates are coalesced on the view and committed asynchronously on the next turn, and no-op size updates no longer dirty the layout. (#48058, #48059 by @focux)ExpoModulesProvider lookup missing the generated class when the app name starts with a digit, which registered no native modules and left release builds on a blank screen. (#48793 by @expo-bot)[iOS] Added SceneGeometry.foregroundScene() for resolving the foregrounded scene without a view. (#48318 by @alanjhughes)
SceneGeometry.foregroundScene() for resolving the foregrounded scene without a view. (#48318 by @alanjhughes)SceneGeometry for reading bounds, safe area, display scale and interface orientation from the scene a view belongs to. (#48168 by @alanjhughes)[Android] Ignore already-settled promises. (#46770 by @jakex7)
[iOS] Added module lifecycle hooks that replace the OnCreate, OnDestroy, OnStartObserving and OnStopObserving DSL components: didCreate, willDestroy,
OnCreate, OnDestroy, OnStartObserving and OnStopObserving DSL components: didCreate, willDestroy, didStartListening and didStopListening. (#47542 by @tsapeta)getModule(implementing:) into a public function. (#47337 by @Ubax)EXC_BAD_ACCESS when encoding native Date values to JavaScript. (#48239, #48240 by @samuelcorsan)Convertible value that keeps the default convertResult implementation, such as CMTime. The value now converts to undefined and logs a warning. (#48266 by @tsapeta)Added a layoutRoot prop to Expo views that marks the shadow node with the RootNodeKind trait, so measure() reports coordinates relative to that node —
layoutRoot prop to Expo views that marks the shadow node with the RootNodeKind trait, so measure() reports coordinates relative to that node — for views that dispatch touch events from their own root view, like RNHostView in @expo/ui. (#48217 by @intergalacticspacehighway)_This version does not introduce any user-facing changes._
This version does not introduce any user-facing changes.
[iOS] ExpoSwiftUI.IgnoreSafeArea that ignores the device and container safe area regions. (#47619 by @nishan) (#47619 by @intergalacticspacehighway)
ExpoSwiftUI.IgnoreSafeArea that ignores the device and container safe area regions. (#47619 by @nishan) (#47619 by @intergalacticspacehighway)canAskAgain returning false for re-requestable permissions in the "Ask every time" state. (#46683 by @alanjhughes)_This version does not introduce any user-facing changes._
This version does not introduce any user-facing changes.
[iOS] @SharedObject now binds @JS methods, properties and the @JS init directly onto the class prototype, so they no longer need Function(…) / Propert
@SharedObject now binds @JS methods, properties and the @JS init directly onto the class prototype, so they no longer need Function(…) / Property(…) / Constructor { … } definition entries. (#47107 by @tsapeta)UIViewHost now hands SwiftUI a disposable isolation container instead of the React-managed view, so leaked autoresizingMask/frame/visibility mutations (including deferred ones from Menu/ContextMenu teardown) can no longer zero-size or hide unrelated components. (#47707 by @cvburgess)@expo/ui community BottomSheet) keeping a stale size after a rapid resize such as dismissing the software keyboard, leaving bottom-anchored content stranded mid-view. The final shadow node size update could be dropped when its one-shot pre-draw listener fired without a following draw pass; the pending update is now also posted to the view so the latest size always flushes. (#47778 by @zayyartun-cgm) (#47810 by @intergalacticspacehighway)this and the arguments buffer synchronously inside the host call and schedule only converted native values, so no JSI-owned wrappers are destroyed off the JS thread after the runtime is torn down. (#47716, #47717 by @AlirezaHadjar)SIGABRT crash when unmounting a SwiftUI view tree that still holds a focused field nested inside a container (e.g. an @expo/ui TextField inside an HStack or LabeledContent in a Form), such as dismissing a modal from a native header button. Resigning the first responder on unmount now recurses through the removed subtree instead of only handling a top-level focusable view. (#47682 by @andreavrr) (#47709 by @intergalacticspacehighway) (#47709 by @andreavrr, @intergalacticspacehighway)hsl()/hsla() color strings failing to parse on some OS versions (observed on the iOS 27.0 beta), caused by regex-literal fragments composed in RegexBuilder blocks. The CSS color patterns are now built from RegexBuilder primitives only. (#47543 by @tsapeta)_This version does not introduce any user-facing changes._
This version does not introduce any user-facing changes.
[iOS] Fix ExpoModulesProvider lookup failing for bundle names with non-identifier characters (e.g. dots). (#46424 by @shawnthye-guru)
ExpoModulesProvider lookup failing for bundle names with non-identifier characters (e.g. dots). (#46424 by @shawnthye-guru)[iOS] Fix a reload deadlock on the new architecture where reloading (from pressing r in the iOS simulator) would freeze the app until the watchdog kil
r in the iOS simulator) would freeze the app until the watchdog killed it. reloadAppAsync now triggers the reload synchronously when already on the main thread instead of always deferring via DispatchQueue.main.async. (#47392 by @brentvatne)[iOS] Return NSNull instead of trapping in the deprecated JavaScriptValue.getAny() when it encounters a unrepresentable value. (#47381 by @alanjhughes…
@expo/ui
BasicTextField component instead of Filled Material TextField. (#46442 by @nishan) (#46442 by @intergalacticspacehighway)expo-modules-jsi
expo-font
Server.resetServerContext(). Server-side font state is now scoped per-render via AsyncLocalStorage. (#46669 by @hassankhan)@expo/cli
expo prebuild clear and regenerate the native folders by default. Pass --no-clean to apply changes to the existing folders instead. (#47209 by @alanjhughes)@expo/require-utils 🥳pod-install
@expo/ui
accessibilityHidden modifier to hide decorative views from VoiceOver and other assistive technologies during element traversal. (#46579 by @ramonclaudio)accessibilityIdentifier modifier to set a stable identifier for UI testing tools such as XCUITest. (#46556 by @ramonclaudio)dynamicTypeSize modifier to set or constrain the Dynamic Type size within a view. Accepts a single size or a { min, max } range, and cascades from <Host> to bound how far text scales at the largest accessibility sizes. (#46540 by @ramonclaudio)children prop to Label component, allowing custom title views (e.g. a VStack with title and subtitle) while preserving native icon spacing and Dynamic Type icon sizing.buttonBorderShape SwiftUI modifier, which reshapes a styled button (for example a glass button) while preserving its native press effect. (#46348 by @nishan) (#46348 by @intergalacticspacehighway)NavigationBar and NavigationBarItem components.listRowSpacing modifier. (#46417 by @qiyangdev)Image component. (#46183 by @cinques)<DisclosureGroup.Label> for custom label style. (#46288 by @kudo)<Collapsible.labelStyle> for custom label style. (#46288 by @kudo)dropShadow and innerShadow modifiers. (#46364 by @duyanhv)imageScale modifier to scale SF Symbols within a view relative to the surrounding text (small, medium, large). (#46774 by @ramonclaudio)onGloballyPositioned modifier, which reports a composable's window position and size. (#46744 by @nishan) (#46744 by @intergalacticspacehighway)onGeometryChange modifier to also report the view's global position (x/y) alongside its size. (#46744 by @nishan) (#46744 by @intergalacticspacehighway)minimumScaleFactor modifier to let text shrink down to a given fraction of its size before truncating. (#46740 by @nishan) (#46740 by @intergalacticspacehighway)get() / set() accessors to useNativeState, as an alternative to reading and writing .value. (#46690 by @nishan) (#46692 by @intergalacticspacehighway)BasicTextField component. (#46442 by @nishan) (#46442 by @intergalacticspacehighway)accessibilityInputLabels modifier to set alternative spoken phrases Voice Control uses to refer to a view (for example "Hang up" for an "End" button). (#46661 by @ramonclaudio)activityBackgroundTint modifier for setting Live Activity background. (#46756 by @jakex7)modifiers prop to ListItem to override its default buttonStyle(.plain). (#47124 by @nishan) (#47124 by @intergalacticspacehighway)seedColor prop to the universal and SwiftUI <Host>, used as the SwiftUI tint on iOS and to derive the primary color scale on web. (#46566 by @zoontek)colorScheme prop on <Host> to override the system color scheme for its subtree, matching native parity. (#46459 by @zoontek)accessibilityElement modifier, which collapses a view's subtree into a single accessibility element via ignore, combine, or contain. (#47156 by @ramonclaudio)redacted, unredacted, privacySensitive, and invalidatableContent modifiers, mapping SwiftUI's redaction family for native skeleton-loading and sensitive-content states. (#47269 by @ramonclaudio)accessibilityAddTraits and accessibilityRemoveTraits SwiftUI modifiers, accepting an array of trait names. (#47387 by @ramonclaudio)strokeBorder modifier with a full StrokeStyle (line width, cap, join, miter limit, dash array, dash phase) for dashed and dotted inset borders that follow the shape's corners. (#47426 by @ramonclaudio)expo-network
expo-router
standard-navigation integration (#46456 by @Ubax)expo-router/drawer (#46635 by @Ubax)tabPress event with isPrevented: true when a disabled tab is tapped, without selecting it. (#46445 by @Ubax)Stack.Toolbar.Badge in header left/right placements (#46537 by @benjaminkomen)Stack.Toolbar.Badge on Stack.Toolbar.Menu icons in header left/right placements (#47276 by @Ubax)unstable_nativeProps to native Stack options. (#47482 by @Ubax)testID and accessibilityLabel props to NativeTabs.Trigger. (#47472 by @ramonclaudio)Theme type from the root expo-router entry point. (#47476 by @eliotgevers)expo-modules-autolinking
expo-modules-jsi
JavaScriptObject.setProperty(_:function:) overloads that create a sync or async host function from the given closure. (#46622 by @tsapeta)JavaScriptUnownedValue, a non-owning, non-copyable value that borrows a jsi::Value for the zero-copy argument-decode fast path. (#46616 by @tsapeta)JavaScriptError can now wrap and throw an arbitrary JS value (not only an Error instance) via init(_:value:), preserving the thrown value's identity when it reaches JavaScript. (#47154 by @tsapeta)createFunction/setProperty overloads taking a UnownedThisSyncFunctionClosure, which receives this as a borrowed JavaScriptUnownedValue instead of an owning JavaScriptValue. Used by host functions that ignore this to skip the per-call owning-value allocation and its weak-runtime traffic. (#46949 by @tsapeta)JavaScriptRuntime to Identifiable with an id based on the underlying runtime, equal across multiple wrappers of the same runtime. (#47068 by @tsapeta)expo-media-library
expo-modules-core
@Record macro that synthesizes a record from a type's stored properties, with no @Field wrappers needed. (#46547 by @tsapeta)@Event macro that turns a function-typed var on a module or shared object into a typed JavaScript event. (#46938 by @tsapeta)@ExpoModule now synthesizes the module's JavaScript name from the class name or its @ExpoModule("CustomName") argument, so a Name(…) definition entry is no longer required. (#46938 by @tsapeta)SharedObject.native(from:) that recovers the native shared object paired with a JavaScript object, with a generic overload that returns the concrete subclass directly. (#47054 by @tsapeta)Module.emit that sends an event directly to the module's own JavaScript object, mirroring SharedObject.emit. Both now share an EventEmitter protocol. (#46555 by @tsapeta)expo-linking
Linking.clearInitialURL() to reset the cached deep-link URL. (#46265 by @gabrieldonadel)expo-image-picker
launchCameraAsync to be invoked on the simulator. (#45923 by @EvanBacon)expo-font
Server.withServerContext(callback) which scopes server-side font loads per render. (#46669 by @hassankhan)expo-contacts
expo-clipboard
expo-brownfield
expo-camera
@expo/package-manager
@expo/cli
tvos and macos autolinking gated by expriments.outOfTreePlatforms (#46344 by @kitten)expo-sqlite
@expo/ui
activityBackgroundTint (#46929 by @theeket)listRowInsets modifier being ignored when every edge is set to 0, so a row can now reset all of its insets. (#47000 by @nishan) (#47000 by @intergalacticspacehighway)FieldGroup rendering an empty row/section when a conditional child (e.g. {condition && <FieldGroup.Section>…</FieldGroup.Section>}) evaluates to false. (##46874 by @dileepapeiris)Pressable/Button taps not registering on community/pager-view pages after the first on physical devices. (#46851 by @nishan) (#46851 by @intergalacticspacehighway)modifiers having no effect when the component derives a modifier of the same type from its props, e.g. buttonStyle on Button always losing to the variant prop. (#46815 by @nishan) (#46815 by @intergalacticspacehighway)expand() and Compose handler registration on ModalBottomSheet. Adds initialFullyExpanded prop to drive initial snap state natively. (#46367 by @duyanhv)community/bottom-sheet blocking touches behind the sheet after it's dismissed. (#46805 by @nishan) (#46805 by @intergalacticspacehighway)Pressable) on community/pager-view pages not responding, or triggering the wrong page's handler, after navigating between pages. (#46778 by @nishan) (#46778 by @intergalacticspacehighway)font, dynamicTypeSize, and resizable modifiers not applying to the SwiftUI Image. SF Symbols scale with Dynamic Type when a font modifier sets a textStyle. (#46714 by @ramonclaudio)ScrollView nested scrolling inside BottomSheet. (#46544 by @nishan) (#46544 by @intergalacticspacehighway)Host with matchContents is used inside React Native Screens. (#46604 by @nishan) (#46604 by @intergalacticspacehighway)PagerView offsetting ScrollView by safe area insets. (#46637 by @nishan) (#46637 by @intergalacticspacehighway)SegmentedControl being overlapped by sibling components inside a ScrollView, by disabling the Host safe area insets. (#46575 by @nishan) (#46575 by @intergalacticspacehighway)DateTimePicker, MenuView, Picker, and Slider applying safe area insets (including keyboard avoidance) twice, by disabling the Host safe area insets (ignoreSafeArea="all"). (#46721 by @nishan) (#46721 by @intergalacticspacehighway)TextField jiggling the surrounding content while its label animates on focus (a Material 3 expressive motion spring overshoot). (#46568 by @nishan) (#46568 by @intergalacticspacehighway)BottomSheet animating open from the bottom-left corner in fitToContents mode. (#46546 by @nishan) (#46546 by @intergalacticspacehighway)TextField and SecureField worklet onTextChange firing more than once per keystroke (when a change triggers reformatting) and on programmatic text updates. (#46483 by @nishan) (#46483 by @intergalacticspacehighway)font modifier dropping Dynamic Type scaling (relativeTo) and weight on concatenated Text runs. The Text-concatenation path now resolves the same Font as the view path. (#46509 by @ramonclaudio)TextInput ignoring style backgroundColor / borderWidth and not applying textAlign to the placeholder. (#46441 by @duyanhv)Switch alignment when label is provided (#47088 by @rklomp)ListItem stretching a fixed-size raw RN view in its leading/trailing slot to fill the row instead of honoring its size, matching Android. (#46883 by @david-videau-ortega) (#47236 by @nishan) (#47236 by @intergalacticspacehighway)@expo-ui/community/datetime-picker dialog ignoring minimumDate/maximumDate for its year range, so the calendar and year picker no longer always span 1900–2100. (#47206 by @vioodle) (#47213 by @nishan) (#47213 by @vioodle, @intergalacticspacehighway)FlatList) inside @expo/ui/community/bottom-sheet not scrolling when the <BottomSheet> is mounted inside another same-orientation list (such as a FlatList header). (#47197 by @nishan) (#47197 by @intergalacticspacehighway)FlatList, ScrollView) inside @expo/ui/community/bottom-sheet not scrolling to the end when using fixed snap points. (#47245 by @nishan) (#47245 by @intergalacticspacehighway)TextField crashing with "String index is out of bounds" on iOS 18 when JS writes new text into a focused field that holds an active text selection. (#47447 by @nishan) (#47447 by @intergalacticspacehighway)community/masked-view doubling offsets and transforms by re-applying the user-supplied style to the inner mask/content View wrappers. (#47067 by @tsushanth)DatePicker style (community/datetime-picker display="inline") rendering undersized on mount and jumping to its correct size on the first tap. (#47062 by @etiennetalbot) (#47465 by @nishan) (#47465 by @etiennetalbot, @intergalacticspacehighway)expo-sensors
expo-router
Props type with the options schema, adding the missing redirects, rewrites, platformRoutes, and disableSynchronousScreensUpdates options. (#46677 by @zoontek)unstable_createStandardRouterNavigator (#46737 by @Ubax)jest.setSystemTime across renderRouter (#46978 by @Ubax)extractExactPathFromURL against malformed percent-encoding. (#47526 by @momomuchu)renderRouter ignoring overrides and listing duplicate routes when an override key matches a file in appDir. (#47287 by @wwdrew)expo-modules-autolinking
react-native-reanimated precompile config with react-native-reanimated@4.4.1 upstream defaults, adding the CSS/core/transition and PseudoStyles header mappings along with the missing IOS_CSS_CORE_ANIMATION and USE_ANIMATION_BACKEND feature flags so its XCFramework builds. (#46950 by @zoontek)expo-modules-macros-plugin. (#46294 by @kudo)react-native-reanimated precompile config with react-native-reanimated@4.5.0's generated component and native view sources. (#47201 by @lukmccall)ios.usePrecompiledModules: false even when EXPO_USE_PRECOMPILED_MODULES is already set in the environment (e.g. EAS Build). (#46983 by @ryanda9910)ENABLE_CROSS_RUNTIME_STACK_TRACES flag to the react-native-worklets precompile config so its prebuilt XCFramework matches the package's staticFlags.json. (#47478 by @alanjhughes)pre_install hook (e.g. @rnmapbox/maps) — both the dynamic frameworks and the pods that link against them — instead of forcing them back to static libraries. (#47500 by @kudo)expo-module-scripts
expo-modules-jsi
sed error when building in an environment that uses GNU sed instead of BSD sed (e.g. a Nix shell). (#46389 by @niteshbalusu11)JavaScriptPromise setup failures instead of trapping the app. (#46106 by @qutrek) (#46145 by @mvincentong) (#46145 by @qutrek, @mvincentong)getPropertyAsFunction targets a missing or non-callable property. (#46437 by @tsapeta)getPropertyAsObject targets a non-object property. (#46438 by @tsapeta)JavaScriptPromise that is rejected after the await begins now throws instead of resuming with the rejection value as if fulfilled. (#47154 by @tsapeta)NSNull instead of trapping in the deprecated JavaScriptValue.getAny() when it encounters a unrepresentable value. (#47381 by @alanjhughes)expo-media-library
expo-modules-core
UISupportedInterfaceOrientations~ipad. (#46281 by @bryandent) (#46306 by @mvincentong) (#46306 by @bryandent, @mvincentong)Host double-composing children. (#46304 by @nishan) (#46304 by @intergalacticspacehighway)react-native-worklets's native adapter isn't linked, instead of a misleading "not an instance of Worklet" failure. (#46571 by @chrfalch)Host matchContents views. (#46604 by @nishan) (#46604 by @intergalacticspacehighway)NullPointerException crash when a matchContents view is unmounted while a shadow node size update is pending (e.g. closing a bottom sheet mid-resize). (#46785 by @nishan) (#46785 by @intergalacticspacehighway)Double timestamps in Date Convertible. JS numbers arrive across the JSI bridge as Swift Double; the prior as? Int branch never matched, throwing ConvertingException<Date> whenever a JS caller passed someDate.getTime() to a Date / Date? argument. (#46340 by @kyleasaff)onLayout against detached window to prevent LayoutNode should be attached to an owner crash. (#47085 by @roitium)Host content disappearing before a react-native-screens pop animation finishes, by deferring composition disposal to window detach while the view is still on-screen for a transition. (#45914, #47086 by @aubrey-wodonga) (#47099 by @nishan) (#47099 by @intergalacticspacehighway)Updates.reloadAsync() where the previous AppContext could deallocate before the old runtime finished tearing down, releasing cached JSI objects against a dying runtime on the wrong thread. Its lifetime is now tied to the runtime via native state attached to the global.expo object. (#47051 by @HaiyiMei) (#47080, #47098 by @tsapeta) (#47080, #47098 by @HaiyiMei, @tsapeta)r in the iOS simulator) would freeze the app until the watchdog killed it. reloadAppAsync now triggers the reload synchronously when already on the main thread instead of always deferring via DispatchQueue.main.async. (#47392 by @brentvatne)ExpoModulesProvider lookup failing for bundle names with non-identifier characters (e.g. dots). (#46424 by @shawnthye-guru)expo-contacts
expo-calendar
@platform ios JSDoc annotations to iOS-exclusive APIs: ExpoCalendarReminder class, listReminders(), createReminder(), requestRemindersPermissions(), getRemindersPermissions(), useRemindersPermissions(), AddEventWithFormOptions.url, and AddEventWithFormOptions.alarms. (#46416 by @kota113)UnavailabilityError when iOS-only Reminders and Sources APIs (listReminders(), createReminder(), ExpoCalendarReminder.get/update/delete, requestRemindersPermissions(), getRemindersPermissions(), and getSourcesSync()) are called on non-iOS platforms. (#46416 by @kota113)useRemindersPermissions() on non-iOS platforms instead of throwing. (#46416 by @kota113)expo-blur
BlurTargetView as detached and cancelling their gestures. (#47404 by @efstathiosntonas)expo-camera
videoOrientation API with AVCaptureDevice.RotationCoordinator for the iOS camera preview. (#47172 by @alanjhughes)pictureSize to photo instead of high. (#47173 by @alanjhughes)@expo/cli
@expo/metro-config install from expo customize metro.config.js (#46600 by @kitten)devices:// deep link instead of only bringing the app forward. (#46809 by @krystofwoldrich)Request to DevTools plugin WebSocket handlers instead of IncomingMessage. (#47410 by @krystofwoldrich)loadModule for MCP and DevTools plugin server module loading. (#47139 by @krystofwoldrich)output-metadata.json when resolving APK filenames to support projects that override outputFileName in applicationVariants (#47083 by @NikhilVashistha)expo
gzip / br / zstd expo/fetch responses on Android even when the caller sets their own Accept-Encoding header. (#46398 by @zoontek)bodyUsed leaking across siblings when fetch Response is cloned twice (#46397 by @zoontek)The stream is not in a state that permits close in expo/fetch when native delivers didComplete/didFailWithError after the consumer has already canceled the body stream. (#44909 by @safaiyeh)expo/fetch on Android sending a single 0x00 byte instead of an empty body for body-less POST/PUT/PATCH requests. (#46678 by @zoontek)asyncRoutes failing on Android and iOS with Requiring unknown module (#46870 by @hassankhan)Response.blob() in expo/fetch throwing when the global Blob is react-native's implementation. (#47538 by @kudo)@expo/ui
Button, Checkbox, FieldGroup, Picker, Slider,Switch,TextInput) with shared design tokens, light / dark themes, and keyboard focus styles. (#46258, #46541 by @zoontek)react-native-reanimated dependency from the worklet integration; worklet features rely on react-native-worklets directly. (#46922, #46935 by @nishan) (#46922, #46935 by @intergalacticspacehighway)CLAUDE.md and CONTRIBUTING.md from publishing and fixed side effects. (#47451 by @kudo)expo-modules-autolinking
bannerTitle and serverEntryPoint options to the DevTools plugin module config. (#46764 by @krystofwoldrich)expo-modules-jsi
JavaScriptRef per call: the arguments buffer is now built inside the synchronous assumeIsolated closure instead of being boxed to cross the closure boundary, removing a heap allocation and its retain/release/dealloc from every host call (measured ~10% faster on the no-op @JS host-call floor). (#46949 by @tsapeta)JavaScriptNativeState can now back any jsi::NativeState subtype via a void * factory, so consumers without Swift/C++ interop (e.g. expo-modules-core) can supply their own pointee. expo::NativeState ships from the xcframework as a public C++ header. (#46330 by @tsapeta)NativeArrayBuffer arguments no longer copy the buffer when it's already native-backed. (#46448 by @barthap)JavaScriptUnownedValue and JavaScriptValuesBuffer now cache the runtime as the immortal facebook.jsi.IRuntime instead of the ARC-managed JavaScriptRuntime wrapper, removing per-call retain/release on the argument-decode hot path (measured ~16% faster addNumbers, ~24% faster addStrings). (#46792 by @tsapeta)getExpoNativeState now probes with the specialized hasNativeState<jsi::NativeState> and dynamic-casts the raw pointer once, avoiding a redundant dynamic_pointer_cast on the shared object argument unwrap hot path. (#46712 by @tsapeta)expo-media-library
expo-modules-core
process function that unwraps shared objects to their registry id, so callers can pass shared objects directly as view props instead of unwrapping them manually. (#46212 by @tsapeta)@ExpoModule now synthesizes a _decorateModule that binds the module's @JS functions directly onto the JS object, letting the module holder skip the dynamic definition path for synthesized modules. (#46612 by @tsapeta)react-native-worklets ^0.9.0 in peer dependencies. (#46950 by @zoontek)updateEdgeToEdgeFeatureFlag (#46335 by @zoontek)JavaScriptDecodable / JavaScriptEncodable (composed as JavaScriptCodable), a statically-dispatched, non-erasing conversion path between JavaScript and native values for Expo Modules v2, with conformances for primitives, containers, records, enumerables and Data. (#46893 by @tsapeta)appContext parameter from the JavaScriptCodable conversions; conversions that need the app context now recover it from the runtime via the new public AppContext.from(runtime:). (#47111 by @tsapeta)JavaScriptCodable now maps Int64/UInt64 to a JS BigInt for lossless 64-bit round-tripping, and Int/UInt throw when encoding a value outside JavaScript's safe-integer range. (#46939 by @tsapeta)Exceptions.ArgumentsRangeMismatch exception, thrown by synthesized @JS function bindings when a JavaScript caller passes a number of arguments outside the accepted range. (#46901 by @tsapeta)SharedObject::NativeState now derives from expo::NativeState so the Swift wrapper can be recovered from the JS side via getNativeState, laying the groundwork for native-state-based shared object lookup. (#46330 by @tsapeta)SharedObject is now paired with its JS counterpart through a SharedObjectNativeState attached to the JS object, so registry lookups in both directions go through the native state and fall back to the legacy id-based path. (#46712 by @tsapeta)NativeArrayBuffer arguments no longer copy the buffer when it's already native-backed. (#46448 by @barthap)react-native-worklets holder instead of the reanimated _WORKLET_RUNTIME global; installOnUIRuntime now takes the holder from getUIRuntimeHolder(). (#46922, #46935 by @nishan) (#46922, #46935 by @intergalacticspacehighway)expo-image-picker
expo-modules-core Platform in favor of inline window/document checks. (#45923 by @EvanBacon)expo-gl
createContextAsync and destroyContextAsync methods which purpose wasn't documented and was confusing. (#47200 by @HubertBer)expo-font
@expo/cli
@expo/ws-tunnel@^2.0.0 (#46696 by @kitten)serverEntryPoint that handles HTTP requests and WebSocket connections in the Expo CLI process, and a bannerTitle shown in the CLI startup banner. (#46764 by @krystofwoldrich)expo
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
[Android] Fixed Expo UI re-compose when switching screens in react-native-screens. (#46650 by @kudo)
[iOS] Added the @Record macro that synthesizes a record from a type's stored properties, with no @Field wrappers needed. (#46547 by @tsapeta)
@Record macro that synthesizes a record from a type's stored properties, with no @Field wrappers needed. (#46547 by @tsapeta)Host matchContents views. (#46604 by @nishan) (#46604 by @intergalacticspacehighway)NullPointerException crash when a matchContents view is unmounted while a shadow node size update is pending (e.g. closing a bottom sheet mid-resize). (#46785 by @nishan) (#46785 by @intergalacticspacehighway)Double timestamps in Date Convertible. JS numbers arrive across the JSI bridge as Swift Double; the prior as? Int branch never matched, throwing ConvertingException<Date> whenever a JS caller passed someDate.getTime() to a Date / Date? argument. (#46340 by @kyleasaff)[iOS] Propagate async-function promise construction failures instead of trapping the app. (#46106 by @qutrek) (#46145 by @mvincentong) (#46145 by @qut
UISupportedInterfaceOrientations~ipad. (#46281 by @bryandent) (#46306 by @mvincentong) (#46306 by @bryandent, @mvincentong)react-native-worklets's native adapter isn't linked, instead of a misleading "not an instance of Worklet" failure. (#46571 by @chrfalch)UISupportedInterfaceOrientations~ipad. (#46281 by @bryandent) (#46306 by @mvincentong)Host double-composing children. (#46304 by @nishan)react-native-worklets's native adapter isn't linked, instead of a misleading "not an instance of Worklet" failure. (#46571 by @chrfalch)Your coding agent can read these notes before it upgrades. Set up the MCP server →