Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home

`ANDROID_SDK_ROOT` environmental variable should be set or configured via `local.properties` file in `android` folder of the native project you're working with.

### (Optional) Speed up Android native builds with ccache

[ccache](https://ccache.dev/) caches C/C++ compilation results so rebuilds of native code are nearly instant when source files haven't changed.

1. Install ccache: `brew install ccache`
2. Add to your `~/.zshrc` (or `~/.bashrc`):
```sh
export CMAKE_C_COMPILER_LAUNCHER="ccache"
export CMAKE_CXX_COMPILER_LAUNCHER="ccache"
```
3. Enable precompiled header support (required by some modules like `expo-modules-core`):
```sh
ccache -o sloppiness=pch_defines,time_macros
```

The repo's `.envrc` automatically sets `CCACHE_BASEDIR` via direnv, so cache is shared across git worktrees with no extra setup.

### Set up iOS

If you will be working with the iOS project, ensure **ruby 3.3** is installed on your machine. macOS comes with ruby 2.6, which is not supported in this repository; if you use Homebrew you can just run `brew install ruby@3.3`. You will also need to have the latest stable version of Xcode installed, along with Xcode command line tools.
Expand Down
4 changes: 1 addition & 3 deletions apps/bare-expo/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -564,11 +564,9 @@ PODS:
- Yoga
- ExpoModulesJSI (56.0.2):
- React-Core
- React-runtimescheduler
- ReactCommon
- ExpoModulesJSI/Tests (56.0.2):
- React-Core
- React-runtimescheduler
- ReactCommon
- ExpoModulesTestCore (56.0.0):
- ExpoModulesCore
Expand Down Expand Up @@ -4019,7 +4017,7 @@ SPEC CHECKSUMS:
ExpoMediaLibrary: ee2d74d5e52154305b8229dcb5c4319c84f30311
ExpoMeshGradient: baf62012104fd9c1719de67f88c69958abcd2ed1
ExpoModulesCore: 5bca19db7db63ab6b60af8b6853f05e7d41fda4c
ExpoModulesJSI: 7312f97b995c769bbfa60182be4dc47814a0a59c
ExpoModulesJSI: 0740aeb1d9d2d3a7e4cd3368b09835d59cba0eb6
ExpoModulesTestCore: 5660ab6b5928747366d4946580622a578865696a
ExpoModulesWorklets: f6674212fdcd312c11642b1e51b9433ab1940a2f
ExpoModulesWorkletsAdapter: 23fa6f8b59e1096e35849bf4f13210640b896822
Expand Down
2 changes: 1 addition & 1 deletion apps/bare-expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"react-native-pager-view": "6.9.1",
"react-native-reanimated": "4.3.1",
"react-native-safe-area-context": "5.6.2",
"react-native-screens": "4.25.0-beta.3",
"react-native-screens": "4.25.0",
"react-native-svg": "15.15.4",
"react-native-view-shot": "4.0.3",
"react-native-webview": "13.16.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/brownfield-tester/expo-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"react-native-worklets": "0.8.3",
"react-native-reanimated": "~4.3.1",
"react-native-safe-area-context": "~5.6.2",
"react-native-screens": "~4.25.0-beta.3",
"react-native-screens": "~4.25.0",
"react-native-web": "~0.21.0"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#import <RCTAppSetupUtils.h>
#import <React/CoreModulesPlugins.h>
#import <ExpoModulesCore/EXHostWrapper.h>
#import <ExpoModulesCore/EXReactSchedulerDispatch.h>
#import <ExpoModulesCore-Swift.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>


@implementation ExpoGoReactNativeFactory
Expand Down Expand Up @@ -49,8 +51,14 @@ - (void)host:(nonnull RCTHost *)host didInitializeRuntime:(facebook::jsi::Runtim
ExpoAppInstance *appInstance = (ExpoAppInstance *)self.delegate;
EXAppContext *appContext = [appInstance createExpoGoAppContext];

// Inject and decorate the `global.expo` object
[appContext setRuntime:&runtime];
// See ExpoReactNativeFactory.mm for the rationale behind passing the React
// runtime scheduler + dispatch trampoline alongside the runtime pointer.
auto binding = facebook::react::RuntimeSchedulerBinding::getBinding(runtime);
auto scheduler = binding ? binding->getRuntimeScheduler() : nullptr;

[appContext setRuntime:&runtime
scheduler:scheduler.get()
dispatch:scheduler ? reinterpret_cast<const void *>(&expo::dispatchOnReactScheduler) : nullptr];
[appContext setHostWrapper:[[EXHostWrapper alloc] initWithHost:host]];

[appContext registerNativeModules];
Expand Down
16 changes: 7 additions & 9 deletions apps/expo-go/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,9 @@ PODS:
- Yoga
- ExpoModulesJSI (56.0.2):
- React-Core
- React-runtimescheduler
- ReactCommon
- ExpoModulesJSI/Tests (56.0.2):
- React-Core
- React-runtimescheduler
- ReactCommon
- ExpoModulesTestCore (56.0.0):
- ExpoModulesCore
Expand Down Expand Up @@ -3694,7 +3692,7 @@ PODS:
- RNWorklets
- SocketRocket
- Yoga
- RNScreens (4.25.0-beta.3):
- RNScreens (4.25.0):
- boost
- DoubleConversion
- fast_float
Expand All @@ -3721,10 +3719,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNScreens/common (= 4.25.0-beta.3)
- RNScreens/common (= 4.25.0)
- SocketRocket
- Yoga
- RNScreens/common (4.25.0-beta.3):
- RNScreens/common (4.25.0):
- boost
- DoubleConversion
- fast_float
Expand Down Expand Up @@ -4242,7 +4240,7 @@ DEPENDENCIES:
- "RNDateTimePicker (from `../../../node_modules/.pnpm/@react-native-community+datetimepicker@9.1.0_expo@packages+expo_react-native@0.85.3_@ba_4da8b598fd3fe2232b688159ab685884/node_modules/@react-native-community/datetimepicker`)"
- "RNGestureHandler (from `../../../node_modules/.pnpm/react-native-gesture-handler@2.31.1_react-native@0.85.3_@babel+core@7.29.0_@react-nativ_e5f24f573130d9ef91edaa3a7b5d2446/node_modules/react-native-gesture-handler`)"
- "RNReanimated (from `../../../node_modules/.pnpm/react-native-reanimated@4.3.1_patch_hash=1e34e4238541638db96b94d5a2e974e73f3b801788a3d8_1a5e3d09dfc1ab41347a1ceaceaf61bc/node_modules/react-native-reanimated`)"
- "RNScreens (from `../../../node_modules/.pnpm/react-native-screens@4.25.0-beta.3_react-native@0.85.3_@babel+core@7.29.0_@react-native_d946f5d10f696c25c0f95066694ac89d/node_modules/react-native-screens`)"
- "RNScreens (from `../../../node_modules/.pnpm/react-native-screens@4.25.0_react-native@0.85.3_@babel+core@7.29.0_@react-native+jest-p_27bafc37770a4b472b96129a8e818eae/node_modules/react-native-screens`)"
- "RNSVG (from `../../../node_modules/.pnpm/react-native-svg@15.15.4_react-native@0.85.3_@babel+core@7.29.0_@react-native+jest-pres_492c03827e778ae24445fe49da301b55/node_modules/react-native-svg`)"
- "RNWorklets (from `../../../node_modules/.pnpm/react-native-worklets@0.8.3_patch_hash=3f49a21b44ba558989a3366eeff9c92ee331e18b736dbe89_42b4111e02dad0db2c0db5ed881424fc/node_modules/react-native-worklets`)"
- SocketRocket (~> 0.7.1)
Expand Down Expand Up @@ -4624,7 +4622,7 @@ EXTERNAL SOURCES:
RNReanimated:
:path: "../../../node_modules/.pnpm/react-native-reanimated@4.3.1_patch_hash=1e34e4238541638db96b94d5a2e974e73f3b801788a3d8_1a5e3d09dfc1ab41347a1ceaceaf61bc/node_modules/react-native-reanimated"
RNScreens:
:path: "../../../node_modules/.pnpm/react-native-screens@4.25.0-beta.3_react-native@0.85.3_@babel+core@7.29.0_@react-native_d946f5d10f696c25c0f95066694ac89d/node_modules/react-native-screens"
:path: "../../../node_modules/.pnpm/react-native-screens@4.25.0_react-native@0.85.3_@babel+core@7.29.0_@react-native+jest-p_27bafc37770a4b472b96129a8e818eae/node_modules/react-native-screens"
RNSVG:
:path: "../../../node_modules/.pnpm/react-native-svg@15.15.4_react-native@0.85.3_@babel+core@7.29.0_@react-native+jest-pres_492c03827e778ae24445fe49da301b55/node_modules/react-native-svg"
RNWorklets:
Expand Down Expand Up @@ -4682,7 +4680,7 @@ SPEC CHECKSUMS:
ExpoMailComposer: e202b670f62063851ed74c964034037312d523a8
ExpoMediaLibrary: ee2d74d5e52154305b8229dcb5c4319c84f30311
ExpoModulesCore: 2a0440b73015179c83c0bd92e2ffdf8decb41c00
ExpoModulesJSI: 7312f97b995c769bbfa60182be4dc47814a0a59c
ExpoModulesJSI: 0740aeb1d9d2d3a7e4cd3368b09835d59cba0eb6
ExpoModulesTestCore: 5660ab6b5928747366d4946580622a578865696a
ExpoModulesWorklets: f6674212fdcd312c11642b1e51b9433ab1940a2f
ExpoModulesWorkletsAdapter: 23fa6f8b59e1096e35849bf4f13210640b896822
Expand Down Expand Up @@ -4824,7 +4822,7 @@ SPEC CHECKSUMS:
RNDateTimePicker: 73ffdd45f0ce1d00ff981031679a05206e619fdc
RNGestureHandler: f0d7f370292ab1ff422eac5a6cbae6feef14bb98
RNReanimated: cde3c8091894bc33108f57ee08f05a63760f7a96
RNScreens: 4e2c5f6f16b001928717ed8e508f929544137a4f
RNScreens: 82303e628dc897156e686705597f2bbcbfa027c3
RNSVG: c9d7c940ad9655eba72c5b9ca7b017c95bb58083
RNWorklets: 057f16d520cd6d64f85e0dcd7565ed3f673ae9dc
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
Expand Down
2 changes: 1 addition & 1 deletion apps/expo-go/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"react-native-reanimated": "4.3.1",
"react-native-safe-area-context": "5.7.0",
"react-native-svg": "15.15.4",
"react-native-screens": "4.25.0-beta.3",
"react-native-screens": "4.25.0",
"react-native-view-shot": "4.0.3",
"react-native-webview": "13.16.1",
"react-native-worklets": "0.8.3"
Expand Down
2 changes: 1 addition & 1 deletion apps/native-component-list/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
"react-native-paper": "^5.12.5",
"react-native-reanimated": "4.3.1",
"react-native-safe-area-context": "5.6.2",
"react-native-screens": "4.25.0-beta.3",
"react-native-screens": "4.25.0",
"react-native-svg": "15.15.4",
"react-native-view-shot": "4.0.3",
"react-native-web": "~0.21.0",
Expand Down
94 changes: 75 additions & 19 deletions apps/native-component-list/src/screens/UI/ScrollViewScreen.ios.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { Host, ScrollView, VStack, Text, RoundedRectangle } from '@expo/ui/swift-ui';
import { frame, foregroundStyle, padding, font } from '@expo/ui/swift-ui/modifiers';
import { HStack, Host, ScrollView, VStack, Text, RoundedRectangle } from '@expo/ui/swift-ui';
import {
frame,
foregroundStyle,
padding,
font,
scrollIndicators,
} from '@expo/ui/swift-ui/modifiers';

export default function ScrollViewScreen() {
import { ScrollPage, Section } from '../../components/Page';

function VerticalExample() {
return (
<Host style={{ flex: 1 }}>
<Host style={{ height: 240 }}>
<ScrollView>
<VStack spacing={12}>
{Array.from({ length: 20 }, (_, i) => (
Expand All @@ -23,29 +31,58 @@ export default function ScrollViewScreen() {
);
}

export function ScrollViewHorizontalScreen() {
function HorizontalExample() {
return (
<Host style={{ flex: 1 }}>
<Host style={{ height: 120 }}>
<ScrollView axes="horizontal">
{Array.from({ length: 20 }, (_, i) => (
<RoundedRectangle
key={i}
cornerRadius={12}
modifiers={[
frame({ width: 100, height: 100 }),
foregroundStyle(`hsl(${i * 18}, 70%, 50%)`),
]}
/>
))}
<HStack spacing={8}>
{Array.from({ length: 20 }, (_, i) => (
<RoundedRectangle
key={i}
cornerRadius={12}
modifiers={[
frame({ width: 100, height: 100 }),
foregroundStyle(`hsl(${i * 18}, 70%, 50%)`),
]}
/>
))}
</HStack>
</ScrollView>
</Host>
);
}

export function ScrollViewHideIndicatorsScreen() {
function BothAxesExample() {
const rows = 12;
const cols = 12;
return (
<Host style={{ flex: 1 }}>
<ScrollView showsIndicators={false}>
<Host style={{ height: 240 }}>
<ScrollView axes="both">
<VStack spacing={8}>
{Array.from({ length: rows }, (_, r) => (
<HStack key={r} spacing={8}>
{Array.from({ length: cols }, (_, c) => (
<RoundedRectangle
key={c}
cornerRadius={8}
modifiers={[
frame({ width: 80, height: 80 }),
foregroundStyle(`hsl(${(r * cols + c) * 6}, 70%, 55%)`),
]}
/>
))}
</HStack>
))}
</VStack>
</ScrollView>
</Host>
);
}

function HideIndicatorsExample() {
return (
<Host style={{ height: 240 }}>
<ScrollView modifiers={[scrollIndicators('hidden')]}>
<VStack spacing={8}>
{Array.from({ length: 30 }, (_, i) => (
<Text key={i} modifiers={[font({ size: 17 }), padding({ horizontal: 16 })]}>
Expand All @@ -58,6 +95,25 @@ export function ScrollViewHideIndicatorsScreen() {
);
}

export default function ScrollViewScreen() {
return (
<ScrollPage>
<Section title="Vertical (default)">
<VerticalExample />
</Section>
<Section title="Horizontal">
<HorizontalExample />
</Section>
<Section title='axes="both" (2D scroll)'>
<BothAxesExample />
</Section>
<Section title='scrollIndicators("hidden") modifier'>
<HideIndicatorsExample />
</Section>
</ScrollPage>
);
}

ScrollViewScreen.navigationOptions = {
title: 'ScrollView',
};
2 changes: 1 addition & 1 deletion apps/notification-tester/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"react": "19.2.3",
"react-native": "0.85.3",
"react-native-safe-area-context": "5.6.2",
"react-native-screens": "4.25.0-beta.3"
"react-native-screens": "4.25.0"
},
"devDependencies": {
"@types/jest": "^29.5.12",
Expand Down
2 changes: 1 addition & 1 deletion apps/observe-tester/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"react-dom": "19.2.3",
"react-native": "0.85.3",
"react-native-safe-area-context": "5.6.2",
"react-native-screens": "4.25.0-beta.3"
"react-native-screens": "4.25.0"
},
"devDependencies": {
"@expo/config": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion apps/router-e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"react-native": "0.85.3",
"react-native-gesture-handler": "~2.30.0",
"react-native-safe-area-context": "5.6.2",
"react-native-screens": "4.25.0-beta.3",
"react-native-screens": "4.25.0",
"react-native-web": "^0.21.0",
"react-native-webview": "13.16.1"
},
Expand Down
1 change: 1 addition & 0 deletions apps/test-suite/TestModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export function getTestModules() {
require('./tests/JSUnicodeRegexes'),
require('./tests/JSNullishCoalescing'),
require('./tests/JSOptionalChaining'),
require('./tests/JSHermesMisc'),
];

// Expo core modules should run everywhere
Expand Down
3 changes: 2 additions & 1 deletion apps/test-suite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "^2.2.0",
"@react-navigation/native": "^7.1.33",
"@react-navigation/native-stack": "^7.14.5",
"@react-navigation/stack": "^7.8.5",
"async-retry": "^1.1.4",
"expo": "workspace:*",
Expand Down Expand Up @@ -81,8 +82,8 @@
},
"devDependencies": {
"@types/getenv": "^1.0.0",
"@types/jasmine": "^5.1.15",
"@types/invariant": "^2.2.35",
"@types/jasmine": "^5.1.15",
"@types/react": "~19.2.0",
"@types/semver": "^7.7.1"
},
Expand Down
Loading
Loading