Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
14fa753
feat(ios): headers-spec layout + ReactNativeHeaders compose
chrfalch Jun 18, 2026
f9e3aec
refactor(ios): remove clang VFS overlay, resolve headers via frameworks
chrfalch Jun 18, 2026
7673a8e
fix(ios): serve the react/ namespace as a module for SPM consumers
chrfalch Jun 21, 2026
9748a92
fix(cocoapods): install prebuilt RNCore pods as header-less facades
chrfalch Jun 22, 2026
684fcf7
style: apply prettier to ios-prebuild scripts and docs
chrfalch Jun 22, 2026
1f6cdb2
ci(ios): include ReactNativeHeaders.xcframework in the prebuilt core …
chrfalch Jun 22, 2026
bb1ce58
feat(ios): expose allowlisted private React headers in the React modu…
chrfalch Jun 23, 2026
ca4f6ca
feat(ios): emit per-namespace umbrella for React_RCTAppDelegate (R10)
chrfalch Jun 23, 2026
65a1bb0
fix(ios): re-vend RCTFabricComponentsPlugins.h from the React-RCTFabr…
chrfalch Jun 24, 2026
bf98226
fix(ios-prebuild): fail closed when a deps namespace is missing from …
chrfalch Jun 24, 2026
5c8897f
fix(ios-prebuild): stage deps headers in compose-xcframework + sort t…
chrfalch Jun 25, 2026
72768b5
feat(ios-prebuild): embed React.framework's non-header resources for …
chrfalch Jun 22, 2026
9b98582
feat(spm): SwiftPM package generation tooling
chrfalch Jun 20, 2026
3fb64ce
feat(spm): rn-tester + helloworld SPM consumption & test library
chrfalch Jun 20, 2026
d34eb40
feat(spm): drop consumer-side headers compose; don't ship build-only …
chrfalch Jun 22, 2026
d9e0a80
fix(cocoapods): define podspec_dir in RNCoreFacades.generate
chrfalch Jun 25, 2026
a0a1630
feat(spm): redesign `react-native spm` to add/update/deinit; drop fro…
chrfalch Jun 25, 2026
fa3e9cb
fix(spm): Flow/ESLint/Prettier compliance for the SPM tooling
chrfalch Jun 25, 2026
d7bb675
chore(spm): drop in-repo SPM example xcodeprojs from rn-tester/hellow…
chrfalch Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/prebuild-ios-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@ jobs:
pattern: prebuild-ios-core-headers-${{ matrix.flavor }}-*
path: packages/react-native/.build/headers
merge-multiple: true
- name: Download ReactNativeDependencies
if: steps.restore-ios-xcframework.outputs.cache-hit != 'true'
uses: actions/download-artifact@v7
with:
name: ReactNativeDependencies${{ matrix.flavor }}.xcframework.tar.gz
path: /tmp/third-party/
- name: Extract ReactNativeDependencies
if: steps.restore-ios-xcframework.outputs.cache-hit != 'true'
shell: bash
run: |
# ReactNativeHeaders.xcframework (built by the compose step) folds in
# the third-party deps namespaces (folly/glog/boost/...), so the deps
# headers must be staged here too — not just in build-slices.
tar -xzf /tmp/third-party/ReactNativeDependencies${{ matrix.flavor }}.xcframework.tar.gz -C /tmp/third-party/
mkdir -p packages/react-native/third-party/
mv /tmp/third-party/packages/react-native/third-party/ReactNativeDependencies.xcframework packages/react-native/third-party/ReactNativeDependencies.xcframework
- name: Setup Keychain
if: ${{ steps.restore-ios-xcframework.outputs.cache-hit != 'true' && env.REACT_ORG_CODE_SIGNING_P12_CERT != '' }}
uses: apple-actions/import-codesign-certs@v3 # https://github.com/marketplace/actions/import-code-signing-certificates
Expand All @@ -177,7 +193,10 @@ jobs:
if: steps.restore-ios-xcframework.outputs.cache-hit != 'true'
run: |
cd packages/react-native/.build/output/xcframeworks/${{matrix.flavor}}
tar -cz -f ../ReactCore${{matrix.flavor}}.xcframework.tar.gz React.xcframework
# Ship BOTH xcframeworks: React-Core-prebuilt's prepare_command flattens
# ReactNativeHeaders.xcframework's Headers (incl. module.modulemap) into the
# pod. Omitting it leaves consumers without React-Core-prebuilt/Headers/module.modulemap.
tar -cz -f ../ReactCore${{matrix.flavor}}.xcframework.tar.gz React.xcframework ReactNativeHeaders.xcframework
- name: Compress and Rename dSYM
if: steps.restore-ios-xcframework.outputs.cache-hit != 'true'
run: |
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
},
"workspaces": [
"packages/*",
"packages/react-native-test-library/*",
"private/*",
"!private/helloworld"
],
Expand Down
11 changes: 11 additions & 0 deletions packages/react-native-test-library/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Generated SPM artifacts (written by setup-ios-spm.js's earlier in-place
# layout). The current autolinker emits these under the consumer app's
# build/generated/autolinking/ tree instead, so any copy that lands here is
# stale and should not be committed.
Package.swift
Package.resolved
include/

# SwiftPM caches
.build/
.swiftpm/
11 changes: 11 additions & 0 deletions packages/react-native-test-library/apple/TestLibraryApple.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <React/RCTBridgeModule.h>

@interface TestLibraryApple : NSObject <RCTBridgeModule>
@end
29 changes: 29 additions & 0 deletions packages/react-native-test-library/apple/TestLibraryApple.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "TestLibraryApple.h"

// Synth library products are emitted as .library(type: .dynamic, ...), so SPM
// wraps each autolinked dep as a Foo.framework under PackageFrameworks/. That
// gives angle-bracket imports the standard <Module/Header.h> resolution path,
// matching how most React Native libraries already organize their headers.
#import <ReactNativeTestLibraryCommon/TestLibraryCommon.h>

@implementation TestLibraryApple

RCT_EXPORT_MODULE()

RCT_EXPORT_METHOD(echo
: (NSString *)message resolve
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject)
{
NSString *prefix = [TestLibraryCommon defaultPrefix];
resolve([NSString stringWithFormat:@"%@apple: %@", prefix, message]);
}

@end
23 changes: 23 additions & 0 deletions packages/react-native-test-library/apple/TestLibraryApple.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::Spec.new do |s|
s.name = "TestLibraryApple"
s.version = package["version"]
s.summary = package["description"]
s.homepage = "https://github.com/facebook/react-native"
s.license = "MIT"
s.platforms = min_supported_versions
s.author = "Meta Platforms, Inc. and its affiliates"
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "#{s.version}" }
s.source_files = "*.{h,m,mm,swift}"
s.requires_arc = true

install_modules_dependencies(s)
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* Smoke test that the SPM autolinker excludes `__tests__/` directories from
* the `sources:` allowlist. If this file ever ends up in a target's sources,
* the build fails immediately with an unresolved header — making the
* regression loud.
*/

#include <this/header/intentionally/does/not/exist.h>

static_assert(false, "TestLibraryAppleTests.cpp must not be compiled by the SPM autolinker");
3 changes: 3 additions & 0 deletions packages/react-native-test-library/apple/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type {Greeting} from 'react-native-test-library-common';

export function greet(g: Greeting): Promise<string>;
28 changes: 28 additions & 0 deletions packages/react-native-test-library/apple/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/

'use strict';

import type {Greeting} from 'react-native-test-library-common';

import {NativeModules, Platform} from 'react-native';
import {formatGreeting} from 'react-native-test-library-common';

export function greet(g: Greeting): Promise<string> {
const TestLibraryApple = NativeModules.TestLibraryApple;
if (TestLibraryApple == null) {
return Promise.reject(
new Error(
`react-native-test-library-apple: native module unavailable on ${Platform.OS}. This package is iOS-only; install a platform-specific sibling (e.g. react-native-test-library-android) for cross-platform coverage.`,
),
);
}
return TestLibraryApple.echo(formatGreeting(g));
}
31 changes: 31 additions & 0 deletions packages/react-native-test-library/apple/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "react-native-test-library-apple",
"version": "0.87.0-main",
"description": "Apple platform implementation for the React Native autolinking fixture. Depends on react-native-test-library-common; used to validate iOS/macOS autolinking discovery and transitive native dependency resolution.",
"private": true,
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
"files": [
"index.js",
"index.d.ts",
"react-native.config.js",
"TestLibraryApple.podspec",
"TestLibraryApple.h",
"TestLibraryApple.mm"
],
"keywords": [
"react-native",
"fixture",
"autolinking",
"ios",
"macos"
],
"dependencies": {
"react-native-test-library-common": "0.87.0-main"
},
"peerDependencies": {
"react": "*",
"react-native": "1000.0.0"
}
}
22 changes: 22 additions & 0 deletions packages/react-native-test-library/apple/react-native.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @noflow
*/

'use strict';

module.exports = {
dependency: {
platforms: {
ios: {},
},
},
spm: {
dependencies: ['react-native-test-library-common'],
},
};
15 changes: 15 additions & 0 deletions packages/react-native-test-library/common/TestLibraryCommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <React/RCTBridgeModule.h>

@interface TestLibraryCommon : NSObject <RCTBridgeModule>

/** Shared prefix used by other test-library packages that depend on common. */
+ (NSString *)defaultPrefix;

@end
26 changes: 26 additions & 0 deletions packages/react-native-test-library/common/TestLibraryCommon.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "TestLibraryCommon.h"

@implementation TestLibraryCommon

RCT_EXPORT_MODULE()

+ (NSString *)defaultPrefix
{
return @"[common] ";
}

RCT_EXPORT_METHOD(version
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject)
{
resolve(@"common@0.87.0-main");
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::Spec.new do |s|
s.name = "TestLibraryCommon"
s.version = package["version"]
s.summary = package["description"]
s.homepage = "https://github.com/facebook/react-native"
s.license = "MIT"
s.platforms = min_supported_versions
s.author = "Meta Platforms, Inc. and its affiliates"
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "#{s.version}" }
s.source_files = "*.{h,m,mm,swift}"
s.requires_arc = true

install_modules_dependencies(s)
end
7 changes: 7 additions & 0 deletions packages/react-native-test-library/common/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type Greeting = Readonly<{
name: string;
language: string;
}>;

export function formatGreeting(g: Greeting): string;
export function getVersion(): Promise<string>;
34 changes: 34 additions & 0 deletions packages/react-native-test-library/common/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/

'use strict';

import {NativeModules, Platform} from 'react-native';

export type Greeting = Readonly<{
name: string,
language: string,
}>;

export function formatGreeting(g: Greeting): string {
return `[${g.language}] Hello, ${g.name}!`;
}

export function getVersion(): Promise<string> {
const TestLibraryCommon = NativeModules.TestLibraryCommon;
if (TestLibraryCommon == null) {
return Promise.reject(
new Error(
`react-native-test-library-common: native module unavailable on ${Platform.OS}.`,
),
);
}
return TestLibraryCommon.version();
}
24 changes: 24 additions & 0 deletions packages/react-native-test-library/common/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "react-native-test-library-common",
"version": "0.87.0-main",
"description": "Shared JS utilities consumed by react-native-test-library-apple. Used as a fixture for validating autolinking discovery and transitive native dependency resolution in the React Native monorepo.",
"private": true,
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
"files": [
"index.js",
"index.d.ts",
"react-native.config.js",
"TestLibraryCommon.podspec",
"TestLibraryCommon.h",
"TestLibraryCommon.mm"
],
"keywords": [
"react-native",
"fixture",
"autolinking",
"ios",
"macos"
]
}
19 changes: 19 additions & 0 deletions packages/react-native-test-library/common/react-native.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @noflow
*/

'use strict';

module.exports = {
dependency: {
platforms: {
ios: {},
},
},
};
Loading
Loading