diff --git a/.github/file-filters.yml b/.github/file-filters.yml
index 523fb46c4b..e5a868fc92 100644
--- a/.github/file-filters.yml
+++ b/.github/file-filters.yml
@@ -55,6 +55,7 @@ js_test:
sample_react_native:
- 'samples/react-native/**'
- 'samples/react-native-macos/**'
+ - 'samples/react-native-tvos/**'
# Changes to the Expo sample app.
# Triggers: sample-application-expo.yml only.
diff --git a/.github/workflows/sample-application.yml b/.github/workflows/sample-application.yml
index 45ab3001a2..f2af1069d1 100644
--- a/.github/workflows/sample-application.yml
+++ b/.github/workflows/sample-application.yml
@@ -317,6 +317,89 @@ jobs:
name: build-sample-legacy-macos-${{ matrix.build-type }}-no-frameworks-logs
path: samples/react-native-macos/macos/*.log
+ build-tvos:
+ name: Build new tvos ${{ matrix.build-type }}
+ runs-on: macos-26-xlarge
+ needs: [diff_check, detect-changes]
+ if: >-
+ ${{
+ needs.diff_check.outputs.skip_ci != 'true'
+ && needs.detect-changes.outputs.needs_sample_react_native == 'true'
+ && (needs.detect-changes.outputs.sample_react_native == 'true' || needs.detect-changes.outputs.needs_ios == 'true')
+ }}
+ env:
+ SENTRY_DISABLE_AUTO_UPLOAD: "true"
+ strategy:
+ fail-fast: false
+ matrix:
+ build-type: ["dev", "production"]
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+
+ - name: Enable Corepack
+ run: corepack enable
+
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
+ with:
+ package-manager-cache: false
+ node-version: 22
+ cache: "yarn"
+ cache-dependency-path: yarn.lock
+
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1
+ with:
+ working-directory: samples/react-native-tvos
+ ruby-version: "3.3.0" # based on what is used in the sample
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
+ cache-version: 1 # cache the installed gems
+
+ - name: Setup Global Xcode Tools
+ run: which xcbeautify || brew install xcbeautify
+
+ - name: Install SDK Dependencies
+ run: yarn install
+
+ - name: Build SDK
+ run: yarn build
+
+ - name: Install App Pods
+ working-directory: samples/react-native-tvos
+ run: |
+ [[ "${{ matrix.build-type }}" == "production" ]] && export ENABLE_PROD=1 || export ENABLE_PROD=0
+ export ENABLE_NEW_ARCH=1
+
+ ./scripts/pod-install.sh
+
+ - name: Build tvOS App
+ working-directory: samples/react-native-tvos/ios
+ env:
+ # Fix for Xcode 26+ with MetalToolchain: use default Xcode toolchain to avoid
+ # missing Swift compatibility libraries (swiftCompatibility56, etc.)
+ # See: https://github.com/actions/runner-images/issues/13135
+ TOOLCHAINS: com.apple.dt.toolchain.XcodeDefault
+ run: |
+ [[ "${{ matrix.build-type }}" == "production" ]] && export CONFIG='Release' || export CONFIG='Debug'
+ echo "Building $CONFIG"
+ mkdir -p "DerivedData"
+ derivedData="$(cd "DerivedData" ; pwd -P)"
+ set -o pipefail && xcodebuild \
+ -workspace TVOSSample.xcworkspace \
+ -configuration "$CONFIG" \
+ -scheme TVOSSample \
+ -destination 'generic/platform=tvOS Simulator' \
+ ONLY_ACTIVE_ARCH=yes \
+ -derivedDataPath "$derivedData" \
+ build \
+ | tee xcodebuild.log \
+ | xcbeautify --quieter --is-ci --disable-colored-output
+
+ - name: Upload logs
+ if: ${{ always() }}
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: build-sample-new-tvos-${{ matrix.build-type }}-no-frameworks-logs
+ path: samples/react-native-tvos/ios/*.log
+
test-ios:
name: Test ios production REV2
runs-on: ["bitrise_pool_name:tahoe"]
diff --git a/package.json b/package.json
index 11e88a79c0..3cc90c26d5 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
"dev-packages/utils",
"samples/react-native",
"samples/react-native-macos",
+ "samples/react-native-tvos",
"samples/expo",
"performance-tests/TestAppPlain",
"performance-tests/TestAppSentry"
diff --git a/samples/react-native-tvos/.bundle/config b/samples/react-native-tvos/.bundle/config
new file mode 100644
index 0000000000..848943bb52
--- /dev/null
+++ b/samples/react-native-tvos/.bundle/config
@@ -0,0 +1,2 @@
+BUNDLE_PATH: "vendor/bundle"
+BUNDLE_FORCE_RUBY_PLATFORM: 1
diff --git a/samples/react-native-tvos/.gitignore b/samples/react-native-tvos/.gitignore
new file mode 100644
index 0000000000..de99955957
--- /dev/null
+++ b/samples/react-native-tvos/.gitignore
@@ -0,0 +1,75 @@
+# OSX
+#
+.DS_Store
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+**/.xcode.env.local
+
+# Android/IntelliJ
+#
+build/
+.idea
+.gradle
+local.properties
+*.iml
+*.hprof
+.cxx/
+*.keystore
+!debug.keystore
+.kotlin/
+
+# node.js
+#
+node_modules/
+npm-debug.log
+yarn-error.log
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
+# screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/
+
+**/fastlane/report.xml
+**/fastlane/Preview.html
+**/fastlane/screenshots
+**/fastlane/test_output
+
+# Bundle artifact
+*.jsbundle
+
+# Ruby / CocoaPods
+**/Pods/
+/vendor/bundle/
+
+# Temporary files created by Metro to check the health of the file watcher
+.metro-health-check*
+
+# testing
+/coverage
+
+# Yarn
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/sdks
+!.yarn/versions
diff --git a/samples/react-native-tvos/.oxlintrc.json b/samples/react-native-tvos/.oxlintrc.json
new file mode 100644
index 0000000000..7db79a7477
--- /dev/null
+++ b/samples/react-native-tvos/.oxlintrc.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "../../packages/core/node_modules/oxlint/configuration_schema.json",
+ "plugins": ["typescript", "react"],
+ "categories": {
+ "correctness": "error"
+ },
+ "rules": {
+ "no-shadow": "off",
+ "typescript/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "caughtErrors": "none" }],
+ "typescript/no-require-imports": "off",
+ "typescript/no-explicit-any": "off",
+ "react-hooks/exhaustive-deps": "warn"
+ },
+ "ignorePatterns": ["node_modules/**", "ios/**", "android/**"]
+}
diff --git a/samples/react-native-tvos/.prettierrc.js b/samples/react-native-tvos/.prettierrc.js
new file mode 100644
index 0000000000..2ae7b381ed
--- /dev/null
+++ b/samples/react-native-tvos/.prettierrc.js
@@ -0,0 +1,7 @@
+module.exports = {
+ arrowParens: 'avoid',
+ bracketSameLine: true,
+ bracketSpacing: true,
+ singleQuote: true,
+ trailingComma: 'all',
+};
diff --git a/samples/react-native-tvos/.ruby-version b/samples/react-native-tvos/.ruby-version
new file mode 100644
index 0000000000..15a2799817
--- /dev/null
+++ b/samples/react-native-tvos/.ruby-version
@@ -0,0 +1 @@
+3.3.0
diff --git a/samples/react-native-tvos/.watchmanconfig b/samples/react-native-tvos/.watchmanconfig
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/samples/react-native-tvos/.watchmanconfig
@@ -0,0 +1 @@
+{}
diff --git a/samples/react-native-tvos/Gemfile b/samples/react-native-tvos/Gemfile
new file mode 100644
index 0000000000..22a13a9ca4
--- /dev/null
+++ b/samples/react-native-tvos/Gemfile
@@ -0,0 +1,17 @@
+source 'https://rubygems.org'
+
+# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
+# ruby "3.4.0"
+
+gem 'cocoapods', '1.15.2'
+gem 'activesupport', '>= 6.1.7.5', '< 7.3.0'
+gem 'xcodeproj', '< 1.26.0'
+
+# Ruby 3.4.0 has removed some libraries from the standard library.
+gem 'bigdecimal'
+gem 'logger'
+gem 'benchmark'
+gem 'mutex_m'
+gem "abbrev"
+gem "csv"
+gem "ostruct"
diff --git a/samples/react-native-tvos/Gemfile.lock b/samples/react-native-tvos/Gemfile.lock
new file mode 100644
index 0000000000..5d7e192596
--- /dev/null
+++ b/samples/react-native-tvos/Gemfile.lock
@@ -0,0 +1,172 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.8)
+ abbrev (0.1.2)
+ activesupport (7.2.3.2)
+ base64
+ benchmark (>= 0.3)
+ bigdecimal
+ concurrent-ruby (~> 1.0, >= 1.3.1)
+ connection_pool (>= 2.2.5)
+ drb
+ i18n (>= 1.6, < 2)
+ logger (>= 1.4.2)
+ minitest (>= 5.1, < 6)
+ securerandom (>= 0.3)
+ tzinfo (~> 2.0, >= 2.0.5)
+ addressable (2.9.0)
+ public_suffix (>= 2.0.2, < 8.0)
+ algoliasearch (1.27.5)
+ httpclient (~> 2.8, >= 2.8.3)
+ json (>= 1.5.1)
+ atomos (0.1.3)
+ base64 (0.3.0)
+ benchmark (0.5.0)
+ bigdecimal (4.1.2)
+ claide (1.1.0)
+ cocoapods (1.15.2)
+ addressable (~> 2.8)
+ claide (>= 1.0.2, < 2.0)
+ cocoapods-core (= 1.15.2)
+ cocoapods-deintegrate (>= 1.0.3, < 2.0)
+ cocoapods-downloader (>= 2.1, < 3.0)
+ cocoapods-plugins (>= 1.0.0, < 2.0)
+ cocoapods-search (>= 1.0.0, < 2.0)
+ cocoapods-trunk (>= 1.6.0, < 2.0)
+ cocoapods-try (>= 1.1.0, < 2.0)
+ colored2 (~> 3.1)
+ escape (~> 0.0.4)
+ fourflusher (>= 2.3.0, < 3.0)
+ gh_inspector (~> 1.0)
+ molinillo (~> 0.8.0)
+ nap (~> 1.0)
+ ruby-macho (>= 2.3.0, < 3.0)
+ xcodeproj (>= 1.23.0, < 2.0)
+ cocoapods-core (1.15.2)
+ activesupport (>= 5.0, < 8)
+ addressable (~> 2.8)
+ algoliasearch (~> 1.0)
+ concurrent-ruby (~> 1.1)
+ fuzzy_match (~> 2.0.4)
+ nap (~> 1.0)
+ netrc (~> 0.11)
+ public_suffix (~> 4.0)
+ typhoeus (~> 1.0)
+ cocoapods-deintegrate (1.0.5)
+ cocoapods-downloader (2.1)
+ cocoapods-plugins (1.0.0)
+ nap
+ cocoapods-search (1.0.1)
+ cocoapods-trunk (1.6.0)
+ nap (>= 0.8, < 2.0)
+ netrc (~> 0.11)
+ cocoapods-try (1.2.0)
+ colored2 (3.1.2)
+ concurrent-ruby (1.3.8)
+ connection_pool (3.0.2)
+ csv (3.3.6)
+ drb (2.2.3)
+ escape (0.0.4)
+ ethon (0.18.0)
+ ffi (>= 1.15.0)
+ logger
+ ffi (1.17.4)
+ fourflusher (2.3.1)
+ fuzzy_match (2.0.4)
+ gh_inspector (1.1.3)
+ httpclient (2.9.0)
+ mutex_m
+ i18n (1.15.2)
+ concurrent-ruby (~> 1.0)
+ json (2.21.2)
+ logger (1.7.0)
+ minitest (5.27.0)
+ molinillo (0.8.0)
+ mutex_m (0.3.0)
+ nanaimo (0.3.0)
+ nap (1.1.0)
+ netrc (0.11.0)
+ ostruct (0.6.3)
+ public_suffix (4.0.7)
+ rexml (3.4.4)
+ ruby-macho (2.5.1)
+ securerandom (0.4.1)
+ typhoeus (1.6.0)
+ ethon (>= 0.18.0)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
+ xcodeproj (1.25.1)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.3.0)
+ rexml (>= 3.3.6, < 4.0)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ abbrev
+ activesupport (>= 6.1.7.5, < 7.3.0)
+ benchmark
+ bigdecimal
+ cocoapods (= 1.15.2)
+ csv
+ logger
+ mutex_m
+ ostruct
+ xcodeproj (< 1.26.0)
+
+CHECKSUMS
+ CFPropertyList (3.0.8) sha256=2c99d0d980536d3d7ab252f7bd59ac8be50fbdd1ff487c98c949bb66bb114261
+ abbrev (0.1.2) sha256=ad1b4eaaaed4cb722d5684d63949e4bde1d34f2a95e20db93aecfe7cbac74242
+ activesupport (7.2.3.2) sha256=ddc90d11dd88086d78ace03407fe3c2a3f5c8853c3c3046313db5ed823ef3312
+ addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af
+ algoliasearch (1.27.5) sha256=26c1cddf3c2ec4bd60c148389e42702c98fdac862881dc6b07a4c0b89ffec853
+ atomos (0.1.3) sha256=7d43b22f2454a36bace5532d30785b06de3711399cb1c6bf932573eda536789f
+ base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
+ benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c
+ bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
+ claide (1.1.0) sha256=6d3c5c089dde904d96aa30e73306d0d4bd444b1accb9b3125ce14a3c0183f82e
+ cocoapods (1.15.2) sha256=f0f5153de8d028d133b96f423e04f37fb97a1da0d11dda581a9f46c0cba4090a
+ cocoapods-core (1.15.2) sha256=322650d97fe1ad4c0831a09669764b888bd91c6d79d0f6bb07281a17667a2136
+ cocoapods-deintegrate (1.0.5) sha256=517c2a448ef563afe99b6e7668704c27f5de9e02715a88ee9de6974dc1b3f6a2
+ cocoapods-downloader (2.1) sha256=bb6ebe1b3966dc4055de54f7a28b773485ac724fdf575d9bee2212d235e7b6d1
+ cocoapods-plugins (1.0.0) sha256=725d17ce90b52f862e73476623fd91441b4430b742d8a071000831efb440ca9a
+ cocoapods-search (1.0.1) sha256=1b133b0e6719ed439bd840e84a1828cca46425ab73a11eff5e096c3b2df05589
+ cocoapods-trunk (1.6.0) sha256=5f5bda8c172afead48fa2d43a718cf534b1313c367ba1194cebdeb9bfee9ed31
+ cocoapods-try (1.2.0) sha256=145b946c6e7747ed0301d975165157951153d27469e6b2763c83e25c84b9defe
+ colored2 (3.1.2) sha256=b13c2bd7eeae2cf7356a62501d398e72fde78780bd26aec6a979578293c28b4a
+ concurrent-ruby (1.3.8) sha256=b2f1be836e968ccc78ccfce277ea79c72a88633f22306782c16ff23fb415d1e1
+ connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
+ csv (3.3.6) sha256=aba61e7e507a66f03d45cb1f3c4b6359861c3504038b422962875dce099e4456
+ drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
+ escape (0.0.4) sha256=e49f44ae2b4f47c6a3abd544ae77fe4157802794e32f19b8e773cbc4dcec4169
+ ethon (0.18.0) sha256=b598afc9f30448cb068b850714b7d6948e941476095d04f90a4ac65b8d6efcb2
+ ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf
+ fourflusher (2.3.1) sha256=1b3de61c7c791b6a4e64f31e3719eb25203d151746bb519a0292bff1065ccaa9
+ fuzzy_match (2.0.4) sha256=b5de4f95816589c5b5c3ad13770c0af539b75131c158135b3f3bbba75d0cfca5
+ gh_inspector (1.1.3) sha256=04cca7171b87164e053aa43147971d3b7f500fcb58177698886b48a9fc4a1939
+ httpclient (2.9.0) sha256=4b645958e494b2f86c2f8a2f304c959baa273a310e77a2931ddb986d83e498c8
+ i18n (1.15.2) sha256=00f9eb62412fe593b2a65a97daa75300d37abb8f7202ec748e94b6d46a9dd1b5
+ json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
+ logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
+ minitest (5.27.0) sha256=2d3b17f8a36fe7801c1adcffdbc38233b938eb0b4966e97a6739055a45fa77d5
+ molinillo (0.8.0) sha256=efbff2716324e2a30bccd3eba1ff3a735f4d5d53ffddbc6a2f32c0ca9433045d
+ mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751
+ nanaimo (0.3.0) sha256=aaaedc60497070b864a7e220f7c4b4cad3a0daddda2c30055ba8dae306342376
+ nap (1.1.0) sha256=949691660f9d041d75be611bb2a8d2fd559c467537deac241f4097d9b5eea576
+ netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f
+ ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912
+ public_suffix (4.0.7) sha256=8be161e2421f8d45b0098c042c06486789731ea93dc3a896d30554ee38b573b8
+ rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
+ ruby-macho (2.5.1) sha256=9075e52e0f9270b552a90b24fcc6219ad149b0d15eae1bc364ecd0ac8984f5c9
+ securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
+ typhoeus (1.6.0) sha256=bacc41c23e379547e29801dc235cd1699b70b955a1ba3d32b2b877aa844c331d
+ tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
+ xcodeproj (1.25.1) sha256=9a2310dccf6d717076e86f602b17c640046b6f1dfe64480044596f6f2f13dc84
+
+BUNDLED WITH
+ 4.0.10
diff --git a/samples/react-native-tvos/android/app/build.gradle b/samples/react-native-tvos/android/app/build.gradle
new file mode 100644
index 0000000000..f0eff86c3d
--- /dev/null
+++ b/samples/react-native-tvos/android/app/build.gradle
@@ -0,0 +1,119 @@
+apply plugin: "com.android.application"
+apply plugin: "org.jetbrains.kotlin.android"
+apply plugin: "com.facebook.react"
+
+/**
+ * This is the configuration block to customize your React Native Android app.
+ * By default you don't need to apply any configuration, just uncomment the lines you need.
+ */
+react {
+ /* Folders */
+ // The root of your project, i.e. where "package.json" lives. Default is '../..'
+ // root = file("../../")
+ // The folder where the react-native NPM package is. Default is ../../node_modules/react-native
+ // reactNativeDir = file("../../node_modules/react-native")
+ // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
+ // codegenDir = file("../../node_modules/@react-native/codegen")
+ // The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
+ // cliFile = file("../../node_modules/react-native/cli.js")
+
+ /* Variants */
+ // The list of variants to that are debuggable. For those we're going to
+ // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
+ // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
+ // debuggableVariants = ["liteDebug", "prodDebug"]
+
+ /* Bundling */
+ // A list containing the node command and its flags. Default is just 'node'.
+ // nodeExecutableAndArgs = ["node"]
+ //
+ // The command to run when bundling. By default is 'bundle'
+ // bundleCommand = "ram-bundle"
+ //
+ // The path to the CLI configuration file. Default is empty.
+ // bundleConfig = file(../rn-cli.config.js)
+ //
+ // The name of the generated asset file containing your JS bundle
+ // bundleAssetName = "MyApplication.android.bundle"
+ //
+ // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
+ // entryFile = file("../js/MyApplication.android.js")
+ //
+ // A list of extra flags to pass to the 'bundle' commands.
+ // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
+ // extraPackagerArgs = []
+
+ /* Hermes Commands */
+ // The hermes compiler command to run. By default it is 'hermesc'
+ // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
+ //
+ // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
+ // hermesFlags = ["-O", "-output-source-map"]
+
+ /* Autolinking */
+ autolinkLibrariesWithApp()
+}
+
+/**
+ * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
+ */
+def enableProguardInReleaseBuilds = false
+
+/**
+ * The preferred build flavor of JavaScriptCore (JSC)
+ *
+ * For example, to use the international variant, you can use:
+ * `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+`
+ *
+ * The international variant includes ICU i18n library and necessary data
+ * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
+ * give correct results when using with locales other than en-US. Note that
+ * this variant is about 6MiB larger per architecture than default.
+ */
+def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
+
+android {
+ ndkVersion rootProject.ext.ndkVersion
+ buildToolsVersion rootProject.ext.buildToolsVersion
+ compileSdk rootProject.ext.compileSdkVersion
+
+ namespace "com.tvossample"
+ defaultConfig {
+ applicationId "com.tvossample"
+ minSdkVersion rootProject.ext.minSdkVersion
+ targetSdkVersion rootProject.ext.targetSdkVersion
+ versionCode 1
+ versionName "1.0"
+ }
+ signingConfigs {
+ debug {
+ storeFile file('debug.keystore')
+ storePassword 'android'
+ keyAlias 'androiddebugkey'
+ keyPassword 'android'
+ }
+ }
+ buildTypes {
+ debug {
+ signingConfig signingConfigs.debug
+ }
+ release {
+ // Caution! In production, you need to generate your own keystore file.
+ // see https://reactnative.dev/docs/signed-apk-android.
+ signingConfig signingConfigs.debug
+ minifyEnabled enableProguardInReleaseBuilds
+ proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
+ }
+ }
+}
+
+dependencies {
+ // The version of react-native is set by the React Native Gradle Plugin
+ implementation("com.facebook.react:react-android")
+
+ if (hermesEnabled.toBoolean()) {
+ implementation("com.facebook.react:hermes-android")
+ } else {
+ implementation jscFlavor
+ }
+}
diff --git a/samples/react-native-tvos/android/app/debug.keystore b/samples/react-native-tvos/android/app/debug.keystore
new file mode 100644
index 0000000000..364e105ed3
Binary files /dev/null and b/samples/react-native-tvos/android/app/debug.keystore differ
diff --git a/samples/react-native-tvos/android/app/proguard-rules.pro b/samples/react-native-tvos/android/app/proguard-rules.pro
new file mode 100644
index 0000000000..11b025724a
--- /dev/null
+++ b/samples/react-native-tvos/android/app/proguard-rules.pro
@@ -0,0 +1,10 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
diff --git a/samples/react-native-tvos/android/app/src/debug/AndroidManifest.xml b/samples/react-native-tvos/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000000..ced5aabf9c
--- /dev/null
+++ b/samples/react-native-tvos/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/samples/react-native-tvos/android/app/src/main/AndroidManifest.xml b/samples/react-native-tvos/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..dfb55dcba9
--- /dev/null
+++ b/samples/react-native-tvos/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/react-native-tvos/android/app/src/main/java/com/tvossample/MainActivity.kt b/samples/react-native-tvos/android/app/src/main/java/com/tvossample/MainActivity.kt
new file mode 100644
index 0000000000..1a3b19c075
--- /dev/null
+++ b/samples/react-native-tvos/android/app/src/main/java/com/tvossample/MainActivity.kt
@@ -0,0 +1,20 @@
+package com.tvossample
+
+import com.facebook.react.ReactActivity
+import com.facebook.react.ReactActivityDelegate
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
+import com.facebook.react.defaults.DefaultReactActivityDelegate
+
+class MainActivity : ReactActivity() {
+ /**
+ * Returns the name of the main component registered from JavaScript. This is used to schedule
+ * rendering of the component.
+ */
+ override fun getMainComponentName(): String = "TVOSSample"
+
+ /**
+ * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
+ * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
+ */
+ override fun createReactActivityDelegate(): ReactActivityDelegate = DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
+}
diff --git a/samples/react-native-tvos/android/app/src/main/java/com/tvossample/MainApplication.kt b/samples/react-native-tvos/android/app/src/main/java/com/tvossample/MainApplication.kt
new file mode 100644
index 0000000000..41a7efe604
--- /dev/null
+++ b/samples/react-native-tvos/android/app/src/main/java/com/tvossample/MainApplication.kt
@@ -0,0 +1,28 @@
+package com.tvossample
+
+import android.app.Application
+import com.facebook.react.PackageList
+import com.facebook.react.ReactApplication
+import com.facebook.react.ReactHost
+import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
+import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
+
+class MainApplication :
+ Application(),
+ ReactApplication {
+ override val reactHost: ReactHost by lazy {
+ getDefaultReactHost(
+ context = applicationContext,
+ packageList =
+ PackageList(this).packages.apply {
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // add(MyReactNativePackage())
+ },
+ )
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ loadReactNative(this)
+ }
+}
diff --git a/samples/react-native-tvos/android/app/src/main/res/drawable/rn_edit_text_material.xml b/samples/react-native-tvos/android/app/src/main/res/drawable/rn_edit_text_material.xml
new file mode 100644
index 0000000000..5c25e728ea
--- /dev/null
+++ b/samples/react-native-tvos/android/app/src/main/res/drawable/rn_edit_text_material.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/react-native-tvos/android/app/src/main/res/drawable/tv_banner.png b/samples/react-native-tvos/android/app/src/main/res/drawable/tv_banner.png
new file mode 100644
index 0000000000..6be49d3700
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/drawable/tv_banner.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..a2f5908281
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..1b52399808
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..ff10afd6e1
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..115a4c768a
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..dcd3cd8083
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..459ca609d3
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..8ca12fe024
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..8e19b410a1
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..b824ebdd48
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..4c19a13c23
Binary files /dev/null and b/samples/react-native-tvos/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/samples/react-native-tvos/android/app/src/main/res/values/strings.xml b/samples/react-native-tvos/android/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..12215669ba
--- /dev/null
+++ b/samples/react-native-tvos/android/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ TVOSSample
+
diff --git a/samples/react-native-tvos/android/app/src/main/res/values/styles.xml b/samples/react-native-tvos/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000000..7ba83a2ad5
--- /dev/null
+++ b/samples/react-native-tvos/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/samples/react-native-tvos/android/build.gradle b/samples/react-native-tvos/android/build.gradle
new file mode 100644
index 0000000000..dad99b022a
--- /dev/null
+++ b/samples/react-native-tvos/android/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ ext {
+ buildToolsVersion = "36.0.0"
+ minSdkVersion = 24
+ compileSdkVersion = 36
+ targetSdkVersion = 36
+ ndkVersion = "27.1.12297006"
+ kotlinVersion = "2.1.20"
+ }
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath("com.android.tools.build:gradle")
+ classpath("com.facebook.react:react-native-gradle-plugin")
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
+ }
+}
+
+apply plugin: "com.facebook.react.rootproject"
diff --git a/samples/react-native-tvos/android/gradle.properties b/samples/react-native-tvos/android/gradle.properties
new file mode 100644
index 0000000000..9afe61598f
--- /dev/null
+++ b/samples/react-native-tvos/android/gradle.properties
@@ -0,0 +1,44 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
+org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+
+# Use this property to specify which architecture you want to build.
+# You can also override it from the CLI using
+# ./gradlew -PreactNativeArchitectures=x86_64
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+
+# Use this property to enable support to the new architecture.
+# This will allow you to use TurboModules and the Fabric render in
+# your application. You should enable this flag either if you want
+# to write custom TurboModules/Fabric components OR use libraries that
+# are providing them.
+newArchEnabled=true
+
+# Use this property to enable or disable the Hermes JS engine.
+# If set to false, you will be using JSC instead.
+hermesEnabled=true
+
+# Use this property to enable edge-to-edge display support.
+# This allows your app to draw behind system bars for an immersive UI.
+# Note: Only works with ReactActivity and should not be used with custom Activity.
+edgeToEdgeEnabled=false
diff --git a/samples/react-native-tvos/android/gradle/wrapper/gradle-wrapper.jar b/samples/react-native-tvos/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..8bdaf60c75
Binary files /dev/null and b/samples/react-native-tvos/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/react-native-tvos/android/gradle/wrapper/gradle-wrapper.properties b/samples/react-native-tvos/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..2a84e188b8
--- /dev/null
+++ b/samples/react-native-tvos/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/samples/react-native-tvos/android/gradlew b/samples/react-native-tvos/android/gradlew
new file mode 100755
index 0000000000..ef07e0162b
--- /dev/null
+++ b/samples/react-native-tvos/android/gradlew
@@ -0,0 +1,251 @@
+#!/bin/sh
+
+#
+# Copyright © 2015 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH="\\\"\\\""
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/samples/react-native-tvos/android/gradlew.bat b/samples/react-native-tvos/android/gradlew.bat
new file mode 100644
index 0000000000..11bf182928
--- /dev/null
+++ b/samples/react-native-tvos/android/gradlew.bat
@@ -0,0 +1,99 @@
+@REM Copyright (c) Meta Platforms, Inc. and affiliates.
+@REM
+@REM This source code is licensed under the MIT license found in the
+@REM LICENSE file in the root directory of this source tree.
+
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/react-native-tvos/android/settings.gradle b/samples/react-native-tvos/android/settings.gradle
new file mode 100644
index 0000000000..f7b0e2f790
--- /dev/null
+++ b/samples/react-native-tvos/android/settings.gradle
@@ -0,0 +1,6 @@
+pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
+plugins { id("com.facebook.react.settings") }
+extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
+rootProject.name = 'TVOSSample'
+include ':app'
+includeBuild('../node_modules/@react-native/gradle-plugin')
diff --git a/samples/react-native-tvos/app.json b/samples/react-native-tvos/app.json
new file mode 100644
index 0000000000..518a1ed2fa
--- /dev/null
+++ b/samples/react-native-tvos/app.json
@@ -0,0 +1,4 @@
+{
+ "name": "TVOSSample",
+ "displayName": "TVOSSample"
+}
diff --git a/samples/react-native-tvos/babel.config.js b/samples/react-native-tvos/babel.config.js
new file mode 100644
index 0000000000..f7b3da3b33
--- /dev/null
+++ b/samples/react-native-tvos/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ['module:@react-native/babel-preset'],
+};
diff --git a/samples/react-native-tvos/index.js b/samples/react-native-tvos/index.js
new file mode 100644
index 0000000000..e1dd8be539
--- /dev/null
+++ b/samples/react-native-tvos/index.js
@@ -0,0 +1,10 @@
+/**
+ * @format
+ */
+
+import { AppRegistry } from 'react-native';
+
+import App from './src/App';
+import { name as appName } from './app.json';
+
+AppRegistry.registerComponent(appName, () => App);
diff --git a/samples/react-native-tvos/ios/.xcode.env b/samples/react-native-tvos/ios/.xcode.env
new file mode 100644
index 0000000000..3d5782c715
--- /dev/null
+++ b/samples/react-native-tvos/ios/.xcode.env
@@ -0,0 +1,11 @@
+# This `.xcode.env` file is versioned and is used to source the environment
+# used when running script phases inside Xcode.
+# To customize your local environment, you can create an `.xcode.env.local`
+# file that is not versioned.
+
+# NODE_BINARY variable contains the PATH to the node executable.
+#
+# Customize the NODE_BINARY variable here.
+# For example, to use nvm with brew, add the following line
+# . "$(brew --prefix nvm)/nvm.sh" --no-use
+export NODE_BINARY=$(command -v node)
diff --git a/samples/react-native-tvos/ios/Podfile b/samples/react-native-tvos/ios/Podfile
new file mode 100644
index 0000000000..bc011cfd9b
--- /dev/null
+++ b/samples/react-native-tvos/ios/Podfile
@@ -0,0 +1,34 @@
+# Resolve react_native_pods.rb with node to allow for hoisting
+require Pod::Executable.execute_command('node', ['-p',
+ 'require.resolve(
+ "react-native/scripts/react_native_pods.rb",
+ {paths: [process.argv[1]]},
+ )', __dir__]).strip
+
+platform :tvos, min_ios_version_supported
+prepare_react_native_project!
+
+linkage = ENV['USE_FRAMEWORKS']
+if linkage != nil
+ Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
+ use_frameworks! :linkage => linkage.to_sym
+end
+
+target 'TVOSSample' do
+ config = use_native_modules!
+
+ use_react_native!(
+ :path => config[:reactNativePath],
+ # An absolute path to your application root.
+ :app_path => "#{Pod::Config.instance.installation_root}/.."
+ )
+
+ post_install do |installer|
+ react_native_post_install(
+ installer,
+ config[:reactNativePath],
+ :mac_catalyst_enabled => false,
+ # :ccache_enabled => true
+ )
+ end
+end
diff --git a/samples/react-native-tvos/ios/TVOSSample.xcodeproj/project.pbxproj b/samples/react-native-tvos/ios/TVOSSample.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..5732d04775
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample.xcodeproj/project.pbxproj
@@ -0,0 +1,490 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 0C80B921A6F3F58F76C31292 /* libPods-TVOSSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-TVOSSample.a */; };
+ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
+ 761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
+ 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
+ BE8CC4D9BB9BA685BFF8F10A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 13B07F961A680F5B00A75B9A /* TVOSSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TVOSSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = TVOSSample/Images.xcassets; sourceTree = ""; };
+ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = TVOSSample/Info.plist; sourceTree = ""; };
+ 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = TVOSSample/PrivacyInfo.xcprivacy; sourceTree = ""; };
+ 3B4392A12AC88292D35C810B /* Pods-TVOSSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TVOSSample.debug.xcconfig"; path = "Target Support Files/Pods-TVOSSample/Pods-TVOSSample.debug.xcconfig"; sourceTree = ""; };
+ 5709B34CF0A7D63546082F79 /* Pods-TVOSSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TVOSSample.release.xcconfig"; path = "Target Support Files/Pods-TVOSSample/Pods-TVOSSample.release.xcconfig"; sourceTree = ""; };
+ 5DCACB8F33CDC322A6C60F78 /* libPods-TVOSSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-TVOSSample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = TVOSSample/AppDelegate.swift; sourceTree = ""; };
+ 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = TVOSSample/LaunchScreen.storyboard; sourceTree = ""; };
+ ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0C80B921A6F3F58F76C31292 /* libPods-TVOSSample.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 13B07FAE1A68108700A75B9A /* TVOSSample */ = {
+ isa = PBXGroup;
+ children = (
+ 13B07FB51A68108700A75B9A /* Images.xcassets */,
+ 761780EC2CA45674006654EE /* AppDelegate.swift */,
+ 13B07FB61A68108700A75B9A /* Info.plist */,
+ 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
+ 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */,
+ );
+ name = TVOSSample;
+ sourceTree = "";
+ };
+ 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
+ 5DCACB8F33CDC322A6C60F78 /* libPods-TVOSSample.a */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Libraries;
+ sourceTree = "";
+ };
+ 83CBB9F61A601CBA00E9B192 = {
+ isa = PBXGroup;
+ children = (
+ 13B07FAE1A68108700A75B9A /* TVOSSample */,
+ 832341AE1AAA6A7D00B99B32 /* Libraries */,
+ 83CBBA001A601CBA00E9B192 /* Products */,
+ 2D16E6871FA4F8E400B85C8A /* Frameworks */,
+ BBD78D7AC51CEA395F1C20DB /* Pods */,
+ );
+ indentWidth = 2;
+ sourceTree = "";
+ tabWidth = 2;
+ usesTabs = 0;
+ };
+ 83CBBA001A601CBA00E9B192 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 13B07F961A680F5B00A75B9A /* TVOSSample.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ BBD78D7AC51CEA395F1C20DB /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 3B4392A12AC88292D35C810B /* Pods-TVOSSample.debug.xcconfig */,
+ 5709B34CF0A7D63546082F79 /* Pods-TVOSSample.release.xcconfig */,
+ );
+ path = Pods;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 13B07F861A680F5B00A75B9A /* TVOSSample */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "TVOSSample" */;
+ buildPhases = (
+ C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
+ 13B07F871A680F5B00A75B9A /* Sources */,
+ 13B07F8C1A680F5B00A75B9A /* Frameworks */,
+ 13B07F8E1A680F5B00A75B9A /* Resources */,
+ 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
+ 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
+ E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TVOSSample;
+ productName = TVOSSample;
+ productReference = 13B07F961A680F5B00A75B9A /* TVOSSample.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 83CBB9F71A601CBA00E9B192 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1210;
+ TargetAttributes = {
+ 13B07F861A680F5B00A75B9A = {
+ LastSwiftMigration = 1120;
+ };
+ };
+ };
+ buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "TVOSSample" */;
+ compatibilityVersion = "Xcode 12.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 83CBB9F61A601CBA00E9B192;
+ productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 13B07F861A680F5B00A75B9A /* TVOSSample */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 13B07F8E1A680F5B00A75B9A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
+ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
+ BE8CC4D9BB9BA685BFF8F10A /* PrivacyInfo.xcprivacy in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "$(SRCROOT)/.xcode.env.local",
+ "$(SRCROOT)/.xcode.env",
+ );
+ name = "Bundle React Native code and images";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"\\\"$WITH_ENVIRONMENT\\\" \\\"$REACT_NATIVE_XCODE\\\"\"\n";
+ };
+ 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-TVOSSample/Pods-TVOSSample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-TVOSSample/Pods-TVOSSample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TVOSSample/Pods-TVOSSample-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-TVOSSample-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-TVOSSample/Pods-TVOSSample-resources-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Copy Pods Resources";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-TVOSSample/Pods-TVOSSample-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TVOSSample/Pods-TVOSSample-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 13B07F871A680F5B00A75B9A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 761780ED2CA45674006654EE /* AppDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 13B07F941A680F5B00A75B9A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-TVOSSample.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = TVOSSample/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ OTHER_LDFLAGS = (
+ "$(inherited)",
+ "-ObjC",
+ "-lc++",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
+ PRODUCT_NAME = TVOSSample;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TVOS_DEPLOYMENT_TARGET = 15.1;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 13B07F951A680F5B00A75B9A /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-TVOSSample.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ INFOPLIST_FILE = TVOSSample/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ OTHER_LDFLAGS = (
+ "$(inherited)",
+ "-ObjC",
+ "-lc++",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
+ PRODUCT_NAME = TVOSSample;
+ SWIFT_VERSION = 5.0;
+ TVOS_DEPLOYMENT_TARGET = 15.1;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+ 83CBBA201A601CBA00E9B192 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "c++20";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ /usr/lib/swift,
+ "$(inherited)",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "\"$(SDKROOT)/usr/lib/swift\"",
+ "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
+ "\"$(inherited)\"",
+ );
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ OTHER_CFLAGS = (
+ "$(inherited)",
+ "-DRCT_REMOVE_LEGACY_ARCH=1",
+ );
+ OTHER_CPLUSPLUSFLAGS = (
+ "$(OTHER_CFLAGS)",
+ "-DFOLLY_NO_CONFIG",
+ "-DFOLLY_MOBILE=1",
+ "-DFOLLY_USE_LIBCPP=1",
+ "-DFOLLY_CFG_NO_COROUTINES=1",
+ "-DFOLLY_HAVE_CLOCK_GETTIME=1",
+ "-DRCT_REMOVE_LEGACY_ARCH=1",
+ );
+ PODFILE_DIR = "$(SRCROOT)";
+ REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
+ SDKROOT = appletvos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
+ TVOS_DEPLOYMENT_TARGET = 15.1;
+ USE_HERMES = true;
+ };
+ name = Debug;
+ };
+ 83CBBA211A601CBA00E9B192 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "c++20";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ /usr/lib/swift,
+ "$(inherited)",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "\"$(SDKROOT)/usr/lib/swift\"",
+ "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
+ "\"$(inherited)\"",
+ );
+ MTL_ENABLE_DEBUG_INFO = NO;
+ OTHER_CFLAGS = (
+ "$(inherited)",
+ "-DRCT_REMOVE_LEGACY_ARCH=1",
+ );
+ OTHER_CPLUSPLUSFLAGS = (
+ "$(OTHER_CFLAGS)",
+ "-DFOLLY_NO_CONFIG",
+ "-DFOLLY_MOBILE=1",
+ "-DFOLLY_USE_LIBCPP=1",
+ "-DFOLLY_CFG_NO_COROUTINES=1",
+ "-DFOLLY_HAVE_CLOCK_GETTIME=1",
+ "-DRCT_REMOVE_LEGACY_ARCH=1",
+ );
+ PODFILE_DIR = "$(SRCROOT)";
+ REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
+ SDKROOT = appletvos;
+ TVOS_DEPLOYMENT_TARGET = 15.1;
+ USE_HERMES = true;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "TVOSSample" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 13B07F941A680F5B00A75B9A /* Debug */,
+ 13B07F951A680F5B00A75B9A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "TVOSSample" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 83CBBA201A601CBA00E9B192 /* Debug */,
+ 83CBBA211A601CBA00E9B192 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
+}
diff --git a/samples/react-native-tvos/ios/TVOSSample.xcodeproj/xcshareddata/xcschemes/TVOSSample.xcscheme b/samples/react-native-tvos/ios/TVOSSample.xcodeproj/xcshareddata/xcschemes/TVOSSample.xcscheme
new file mode 100644
index 0000000000..5be368de74
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample.xcodeproj/xcshareddata/xcschemes/TVOSSample.xcscheme
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/react-native-tvos/ios/TVOSSample.xcworkspace/contents.xcworkspacedata b/samples/react-native-tvos/ios/TVOSSample.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..f0b9c3f47e
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/samples/react-native-tvos/ios/TVOSSample/AppDelegate.swift b/samples/react-native-tvos/ios/TVOSSample/AppDelegate.swift
new file mode 100644
index 0000000000..da1dd18005
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample/AppDelegate.swift
@@ -0,0 +1,48 @@
+import UIKit
+import React
+import React_RCTAppDelegate
+import ReactAppDependencyProvider
+
+@main
+class AppDelegate: UIResponder, UIApplicationDelegate {
+ var window: UIWindow?
+
+ var reactNativeDelegate: ReactNativeDelegate?
+ var reactNativeFactory: RCTReactNativeFactory?
+
+ func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
+ ) -> Bool {
+ let delegate = ReactNativeDelegate()
+ let factory = RCTReactNativeFactory(delegate: delegate)
+ delegate.dependencyProvider = RCTAppDependencyProvider()
+
+ reactNativeDelegate = delegate
+ reactNativeFactory = factory
+
+ window = UIWindow(frame: UIScreen.main.bounds)
+
+ factory.startReactNative(
+ withModuleName: "TVOSSample",
+ in: window,
+ launchOptions: launchOptions
+ )
+
+ return true
+ }
+}
+
+class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
+ override func sourceURL(for bridge: RCTBridge) -> URL? {
+ self.bundleURL()
+ }
+
+ override func bundleURL() -> URL? {
+#if DEBUG
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+#else
+ Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+#endif
+ }
+}
diff --git a/samples/react-native-tvos/ios/TVOSSample/Images.xcassets/AppIcon.appiconset/Contents.json b/samples/react-native-tvos/ios/TVOSSample/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..81213230de
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,53 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/samples/react-native-tvos/ios/TVOSSample/Images.xcassets/Contents.json b/samples/react-native-tvos/ios/TVOSSample/Images.xcassets/Contents.json
new file mode 100644
index 0000000000..2d92bd53fd
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample/Images.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/samples/react-native-tvos/ios/TVOSSample/Info.plist b/samples/react-native-tvos/ios/TVOSSample/Info.plist
new file mode 100644
index 0000000000..b7588344c3
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample/Info.plist
@@ -0,0 +1,55 @@
+
+
+
+
+ CADisableMinimumFrameDurationOnPhone
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ TVOSSample
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(MARKETING_VERSION)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ LSRequiresIPhoneOS
+
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+ NSAllowsLocalNetworking
+
+
+ NSLocationWhenInUseUsageDescription
+
+ RCTNewArchEnabled
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+
+
diff --git a/samples/react-native-tvos/ios/TVOSSample/LaunchScreen.storyboard b/samples/react-native-tvos/ios/TVOSSample/LaunchScreen.storyboard
new file mode 100644
index 0000000000..f9a0b7071d
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample/LaunchScreen.storyboard
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/react-native-tvos/ios/TVOSSample/PrivacyInfo.xcprivacy b/samples/react-native-tvos/ios/TVOSSample/PrivacyInfo.xcprivacy
new file mode 100644
index 0000000000..fc90547a7a
--- /dev/null
+++ b/samples/react-native-tvos/ios/TVOSSample/PrivacyInfo.xcprivacy
@@ -0,0 +1,37 @@
+
+
+
+
+ NSPrivacyAccessedAPITypes
+
+
+ NSPrivacyAccessedAPIType
+ NSPrivacyAccessedAPICategoryFileTimestamp
+ NSPrivacyAccessedAPITypeReasons
+
+ C617.1
+
+
+
+ NSPrivacyAccessedAPIType
+ NSPrivacyAccessedAPICategorySystemBootTime
+ NSPrivacyAccessedAPITypeReasons
+
+ 35F9.1
+
+
+
+ NSPrivacyAccessedAPIType
+ NSPrivacyAccessedAPICategoryUserDefaults
+ NSPrivacyAccessedAPITypeReasons
+
+ CA92.1
+
+
+
+ NSPrivacyCollectedDataTypes
+
+ NSPrivacyTracking
+
+
+
diff --git a/samples/react-native-tvos/jest.config.js b/samples/react-native-tvos/jest.config.js
new file mode 100644
index 0000000000..8eb675e9bc
--- /dev/null
+++ b/samples/react-native-tvos/jest.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ preset: 'react-native',
+};
diff --git a/samples/react-native-tvos/metro.config.js b/samples/react-native-tvos/metro.config.js
new file mode 100644
index 0000000000..270023086b
--- /dev/null
+++ b/samples/react-native-tvos/metro.config.js
@@ -0,0 +1,20 @@
+const { withSentryConfig } = require('@sentry/react-native/metro');
+const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
+
+const { withMonorepo } = require('sentry-react-native-samples-utils/metro');
+
+/**
+ * Metro configuration
+ * https://facebook.github.io/metro/docs/configuration
+ *
+ * @type {import('metro-config').MetroConfig}
+ */
+const config = {};
+
+const mergedConfig = mergeConfig(getDefaultConfig(__dirname), config);
+
+const sentryConfig = withSentryConfig(mergedConfig, {
+ annotateReactComponents: true,
+});
+
+module.exports = withMonorepo(sentryConfig);
diff --git a/samples/react-native-tvos/package.json b/samples/react-native-tvos/package.json
new file mode 100644
index 0000000000..b5b0c84004
--- /dev/null
+++ b/samples/react-native-tvos/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "sentry-react-native-tvos-sample",
+ "version": "8.25.0",
+ "private": true,
+ "scripts": {
+ "start": "react-native start",
+ "lint": "npx oxlint",
+ "fix": "npx oxlint --fix",
+ "type-check": "tsc --noEmit",
+ "pod-install-legacy": "cd ios; bundle exec pod install; cd ..",
+ "pod-install-legacy-production": "cd ios; PRODUCTION=1 bundle exec pod install; cd ..",
+ "clean-tvos": "cd ios; rm -rf Podfile.lock Pods build; cd ..",
+ "clean-watchman": "watchman watch-del-all"
+ },
+ "dependencies": {
+ "@sentry/react-native": "8.25.0",
+ "react": "19.2.3",
+ "react-native": "npm:react-native-tvos@0.87.1-0"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.25.2",
+ "@babel/preset-env": "^7.25.3",
+ "@babel/runtime": "^7.25.0",
+ "@react-native-community/cli": "20.1.3",
+ "@react-native-community/cli-platform-android": "20.1.3",
+ "@react-native-community/cli-platform-ios": "20.1.3",
+ "@react-native/babel-preset": "0.87.1",
+ "@react-native/metro-config": "0.87.1",
+ "@react-native/typescript-config": "0.87.1",
+ "@types/react": "^19.0.0",
+ "jest": "^29.6.3",
+ "sentry-react-native-samples-utils": "workspace:^",
+ "typescript": "5.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+}
diff --git a/samples/react-native-tvos/scripts/pod-install.sh b/samples/react-native-tvos/scripts/pod-install.sh
new file mode 100755
index 0000000000..5d1ada6789
--- /dev/null
+++ b/samples/react-native-tvos/scripts/pod-install.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Exit on error
+set -e
+
+thisFilePath=$(dirname "$0")
+
+echo "USE_FRAMEWORKS=$USE_FRAMEWORKS"
+echo "ENABLE_PROD=$ENABLE_PROD"
+echo "ENABLE_NEW_ARCH=$ENABLE_NEW_ARCH"
+
+cd "${thisFilePath}/.."
+bundle install
+
+cd ios
+PRODUCTION=$ENABLE_PROD RCT_NEW_ARCH_ENABLED=$ENABLE_NEW_ARCH bundle exec pod update
+
+cat Podfile.lock | grep $RN_SENTRY_POD_NAME
diff --git a/samples/react-native-tvos/src/App.tsx b/samples/react-native-tvos/src/App.tsx
new file mode 100644
index 0000000000..2b63f4cf94
--- /dev/null
+++ b/samples/react-native-tvos/src/App.tsx
@@ -0,0 +1,84 @@
+/**
+ * Sentry React Native tvOS Sample
+ *
+ * @format
+ */
+
+import React from 'react';
+import {
+ Button,
+ SafeAreaView,
+ ScrollView,
+ StatusBar,
+ StyleSheet,
+ Text,
+ View,
+} from 'react-native';
+
+import * as Sentry from '@sentry/react-native';
+
+import { SENTRY_INTERNAL_DSN } from './dsn';
+
+Sentry.init({
+ dsn: SENTRY_INTERNAL_DSN,
+ // Sets the sample rate to 1.0 to capture 100% of transactions for tracing.
+ tracesSampleRate: 1.0,
+ // Adds more context data to events (IP address, cookies, user, etc.).
+ // Only enabled here for the sample app - gate on user consent in production.
+ // https://docs.sentry.io/platforms/react-native/data-management/data-collected/
+ sendDefaultPii: true,
+});
+
+function App(): React.JSX.Element {
+ return (
+
+
+
+
+ Sentry React Native tvOS
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ body: {
+ padding: 24,
+ },
+ title: {
+ fontSize: 24,
+ fontWeight: '600',
+ marginBottom: 24,
+ },
+ spacer: {
+ height: 12,
+ },
+});
+
+export default Sentry.wrap(App);
diff --git a/samples/react-native-tvos/src/dsn.ts b/samples/react-native-tvos/src/dsn.ts
new file mode 100644
index 0000000000..66bb432ccb
--- /dev/null
+++ b/samples/react-native-tvos/src/dsn.ts
@@ -0,0 +1,8 @@
+import * as Sentry from '@sentry/react-native';
+
+export const SENTRY_INTERNAL_DSN =
+ 'https://1df17bd4e543fdb31351dee1768bb679@o447951.ingest.sentry.io/5428561';
+
+export const getCurrentDsn = () => {
+ return Sentry.getClient()?.getOptions().dsn;
+};
diff --git a/samples/react-native-tvos/tsconfig.json b/samples/react-native-tvos/tsconfig.json
new file mode 100644
index 0000000000..12e604b4b4
--- /dev/null
+++ b/samples/react-native-tvos/tsconfig.json
@@ -0,0 +1,17 @@
+// prettier-ignore
+{
+ "extends": "@react-native/typescript-config",
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
+
+ /* Completeness */
+ "skipLibCheck": true, /* Skip type checking all .d.ts files. */
+ "baseUrl": ".",
+ /* react-native-tvos@0.87.1-0 ships a broken exports "types" pointer
+ (./types_generated/index.d.ts is missing from the package); map
+ react-native to the legacy typings that do ship. */
+ "paths": {
+ "react-native": ["./node_modules/react-native/types/index.d.ts"],
+ },
+ },
+}
diff --git a/yarn.lock b/yarn.lock
index 360cc6aec1..32f9a9470d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8846,6 +8846,23 @@ __metadata:
languageName: node
linkType: hard
+"@react-native-tvos/virtualized-lists@npm:0.87.1-0":
+ version: 0.87.1-0
+ resolution: "@react-native-tvos/virtualized-lists@npm:0.87.1-0"
+ dependencies:
+ invariant: "npm:^2.2.4"
+ nullthrows: "npm:^1.1.1"
+ peerDependencies:
+ "@types/react": ^19.2.0
+ react: "*"
+ react-native: 0.87.1
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 10c0/0e0eeea810ea71bb10734f6cc39d055a91742ad9541ae8f967c03a4589e39faf587021577a1dbdeacc26abf8f26d9e646db7007a512d7a8c47505882acfd9bd7
+ languageName: node
+ linkType: hard
+
"@react-native-vector-icons/common@npm:^12.3.0":
version: 12.3.0
resolution: "@react-native-vector-icons/common@npm:12.3.0"
@@ -11026,6 +11043,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/react@npm:^19.0.0, @types/react@npm:^19.2.0":
+ version: 19.2.18
+ resolution: "@types/react@npm:19.2.18"
+ dependencies:
+ csstype: "npm:^3.2.2"
+ checksum: 10c0/d04216172b4b4362b310017c210dfbe019fb4f4e7dffd0313e70b3acb3051d5c3e76e7e84e3cf4c6a3c824993ffadfe3949e589a6398a09d4200e7670e2962de
+ languageName: node
+ linkType: hard
+
"@types/react@npm:^19.1.0":
version: 19.1.13
resolution: "@types/react@npm:19.1.13"
@@ -11053,15 +11079,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/react@npm:^19.2.0":
- version: 19.2.18
- resolution: "@types/react@npm:19.2.18"
- dependencies:
- csstype: "npm:^3.2.2"
- checksum: 10c0/d04216172b4b4362b310017c210dfbe019fb4f4e7dffd0313e70b3acb3051d5c3e76e7e84e3cf4c6a3c824993ffadfe3949e589a6398a09d4200e7670e2962de
- languageName: node
- linkType: hard
-
"@types/retry@npm:0.12.2":
version: 0.12.2
resolution: "@types/retry@npm:0.12.2"
@@ -26887,6 +26904,52 @@ __metadata:
languageName: node
linkType: hard
+"react-native@npm:react-native-tvos@0.87.1-0":
+ version: 0.87.1-0
+ resolution: "react-native-tvos@npm:0.87.1-0"
+ dependencies:
+ "@react-native-tvos/virtualized-lists": "npm:0.87.1-0"
+ "@react-native/asset-utils": "npm:0.87.1"
+ "@react-native/codegen": "npm:0.87.1"
+ "@react-native/community-cli-plugin": "npm:0.87.1"
+ "@react-native/gradle-plugin": "npm:0.87.1"
+ "@react-native/normalize-colors": "npm:0.87.1"
+ anser: "npm:^1.4.9"
+ ansi-regex: "npm:^5.0.0"
+ babel-plugin-syntax-hermes-parser: "npm:0.36.1"
+ base64-js: "npm:^1.5.1"
+ commander: "npm:^12.0.0"
+ flow-enums-runtime: "npm:^0.0.6"
+ hermes-compiler: "npm:250829098.0.17"
+ invariant: "npm:^2.2.4"
+ memoize-one: "npm:^5.0.0"
+ metro-runtime: "npm:^0.87.0"
+ metro-source-map: "npm:^0.87.0"
+ nullthrows: "npm:^1.1.1"
+ pretty-format: "npm:^29.7.0"
+ promise: "npm:^8.3.0"
+ react-devtools-core: "npm:^6.1.5"
+ react-refresh: "npm:^0.14.0"
+ regenerator-runtime: "npm:^0.13.2"
+ scheduler: "npm:0.27.0"
+ semver: "npm:^7.1.3"
+ stacktrace-parser: "npm:^0.1.10"
+ tinyglobby: "npm:^0.2.15"
+ whatwg-fetch: "npm:^3.0.0"
+ ws: "npm:^7.5.10"
+ yargs: "npm:^17.6.2"
+ peerDependencies:
+ "@types/react": ^19.1.1
+ react: ^19.2.3
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ bin:
+ react-native: cli.js
+ checksum: 10c0/9aa0b7b2cab22031df2b093df870a5023b3bcf571903cbee87ed74f54f6e12887998f6921a99b31cd3e565ee22d2d98f8aefa894ad4ba5b8451d149c474f30d0
+ languageName: node
+ linkType: hard
+
"react-redux@npm:^9.2.0":
version: 9.2.0
resolution: "react-redux@npm:9.2.0"
@@ -28436,6 +28499,29 @@ __metadata:
languageName: unknown
linkType: soft
+"sentry-react-native-tvos-sample@workspace:samples/react-native-tvos":
+ version: 0.0.0-use.local
+ resolution: "sentry-react-native-tvos-sample@workspace:samples/react-native-tvos"
+ dependencies:
+ "@babel/core": "npm:^7.25.2"
+ "@babel/preset-env": "npm:^7.25.3"
+ "@babel/runtime": "npm:^7.25.0"
+ "@react-native-community/cli": "npm:20.1.3"
+ "@react-native-community/cli-platform-android": "npm:20.1.3"
+ "@react-native-community/cli-platform-ios": "npm:20.1.3"
+ "@react-native/babel-preset": "npm:0.87.1"
+ "@react-native/metro-config": "npm:0.87.1"
+ "@react-native/typescript-config": "npm:0.87.1"
+ "@sentry/react-native": "npm:8.25.0"
+ "@types/react": "npm:^19.0.0"
+ jest: "npm:^29.6.3"
+ react: "npm:19.2.3"
+ react-native: "npm:react-native-tvos@0.87.1-0"
+ sentry-react-native-samples-utils: "workspace:^"
+ typescript: "npm:5.0.4"
+ languageName: unknown
+ linkType: soft
+
"sentry-react-native-type-check@workspace:dev-packages/type-check":
version: 0.0.0-use.local
resolution: "sentry-react-native-type-check@workspace:dev-packages/type-check"