Skip to content

chore: sdk maintenance for react-native 0.81+ - #269

Draft
velocitysystems wants to merge 25 commits into
masterfrom
chore/sdk-maintenance
Draft

velocitysystems wants to merge 25 commits into
masterfrom
chore/sdk-maintenance

Conversation

@velocitysystems

@velocitysystems velocitysystems commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

The 2.0.0 release: native SDK updates, the Real User Monitoring network timing fix, packaging and docs fixes, a new React Native 0.81 minimum, and CI that runs each check once.

Merge with "Rebase and merge", not squash. Each commit is a separate change and should stay revertable on its own.

Breaking changes (in the 2.0.0 changelog)

  • React Native 0.81+, React 19.1+, now declared as peer dependencies. raygun4android 6 requires host apps to compile against Android SDK 36, which React Native 0.81 is the first release to use by default
  • Android: compileSdk 36, minSdk 24, Java 17
  • iOS: minimum 15.1, taken from React Native's min_ios_version_supported
  • Node >=20.19.4 in engines, from React Native 0.81

Commits

Commit What changed
chore: remove unused babel and jest dependencies Removes the Babel 6 plugin behind the critical babel-traverse Dependabot alert, plus ts-jest, tsconfig.jest.json and an unused glob dev dependency
ci: type-check the sdk Adds tsc --noEmit to sdk-checks. No job type-checked the SDK before
ci: stop running each check twice per pull request Pushes only trigger CI on master, a new commit cancels a PR's older runs (each master push gets its own concurrency group, so master runs are never cancelled), and path filters skip unaffected workflows. Prettier moves into sdk-checks, pinned to 3.9.8, with a sdk/.prettierignore so a locally built dist/ isn't checked. The workflow token is read-only. Adds Expo Demo CI, which prebuilds and builds ExpoDemo for Android (Ubuntu) and iOS (macOS 26, Xcode 26.6); ExpoDemo had no CI at all
chore: update raygun4android to 6.2.2 Plus compileSdk 36, minSdk 24, Java 17, Timber 5 and hasActiveReactInstance(). Keeps the kotlin-stdlib exclusion (#237): 6.2.2 declares stdlib 2.4.10
fix: point the podspec at the MindscapeHQ repo s.source pointed at a branch on a personal fork. It now points at this repo's v<version> tag. Also uses install_modules_dependencies, and removes unused imports
fix: build dist on pack and publish only runtime files prepublishprepare, which clears and rebuilds dist/ on pack, publish and local install, so a publish never ships a stale build and ExpoDemo's file:../sdk still gets one. A files allowlist stops tests and config files shipping: 1.7.1 shipped 40 files, this ships 35
chore: declare react and react-native peer dependencies and engines react-native >=0.81.0, react >=19.1.0, node >=20.19.4
docs: update requirements and installation for react-native 0.81+ README requirements, installation and Expo sections, including the removed Android services step. Also fixes RELEASING.md and the 1.7.1 changelog entry
chore: fix the prettier and eslint config warnings bracketSameLine, and an explicit React version for eslint-plugin-react. "detect" crashes under ESLint 10
chore: raise the demo's activesupport floor to 7.2.3.1 Clears three moderate alerts. Raises the demo's Ruby requirement to 3.1
chore: ship the MIT license with the npm package sdk/LICENSE, the same text as LICENSE-MIT
fix: key monitored requests with a counter instead of uuid Drops uuid, the SDK's last runtime dependency. uuid 14 has no main field, so apps whose Metro doesn't read package exports couldn't bundle the SDK. This unblocks releasing from master
fix: restore rum network timing on react native 0.80+ Fixes F1: RUM has sent no network timing events on RN 0.80+ since 1.6.0, because the SDK loaded RN's private XHRInterceptor from paths that no longer exist and silently fell back to a do-nothing interceptor. The new NetworkInterceptor.ts wraps XMLHttpRequest itself. Callback errors are logged and never reach the app's request, and a warning is logged if interception isn't possible. Event names upper-case the method and leave out the query string and fragment, as raygun4js, raygun4android and raygun4apple do. The interceptor passes the monitor only the method, URL and request, which is all it uses. The two new monitor tests that expect events fail against the old code
fix: capture fetch requests in rum on expo sdk 56+ Expo SDK 56+ replaces the global fetch with a native one that doesn't use XHR, so it wraps fetch too. RN's own fetch creates its XHR synchronously, so XHRs opened during a fetch call are skipped, and each request is reported once. Checked against Expo 54–57 and whatwg-fetch 3.6.20
chore: release 2.0.0 Version 2.0.0 in sdk/package.json and its lockfile, and the 2.0.0 CHANGELOG.md entry. The demo now points at the 2.0.0 tarball, and its lockfile entry for the SDK, previously stuck on 1.7.0, is regenerated
chore: upgrade the demo to react native 0.87 Regenerates the bare demo's native projects from the RN 0.87.1 template (keeping its module name), updates its libraries to their latest, and fixes its tsconfig. Checkbox stays on 0.5.20 because 0.6.0's iOS codegen is broken, with BuildConfig turned on for that module under AGP 9. App code unchanged
chore: upgrade ExpoDemo to expo sdk 57 Expo 57.0.24 via expo install --fix (RN 0.86.3, TypeScript 6). ExpoDemo couldn't start on master, because #256 moved it to TypeScript 7, which Expo's CLI can't read tsconfig.json with. App code unchanged
fix: resolve the type errors in the demo screens Type-only fixes so tsc passes on the bare demo: e as Error in catch blocks, undefined for two optional fields the SDK normalises anyway, a component type for the checkbox, and null from a function called in JSX. Behaviour unchanged
chore: remove ExpoDemo's obsolete plugin, packages and scripts Removes withRaygunAndroid.js, which added the nonexistent Android services (F3), the unused React Navigation packages, and the broken test/reset-project scripts with their Jest setup
chore: install the sdk into the demo from ../sdk The bare demo links ../sdk like ExpoDemo, instead of a gitignored tarball that made its README fail on a fresh clone. Retires the SDK's tarball scripts and copyfiles/run-script-os
chore: remove stale ios declarations and unused code Removes six declared-but-nonexistent methods and an unused function from the iOS sources, and adds a missing prototype, so the SDK compiles with no warnings. Behaviour unchanged

Verification

  • npm ci, tsc --noEmit, npm test (40 passed, 20 of them new RUM tests), ESLint and Prettier all pass locally, with Prettier also run with dist/ built. npm audit finds 0 vulnerabilities; the only install warnings left are deprecation notices for glob@7/inflight, which come from Jest 29 and copyfiles

  • Every commit that changes the SDK's dependencies has a lockfile that matches its package.json

  • npm pack --dry-run builds dist/ via prepare and lists 33 files. Stale files planted in dist/ and a test file under android/build/ were not packed

  • raygun4android 6.2.2's published files declare minCompileSdk=36 and kotlin-stdlib 2.4.10. React Native 0.81's defaults are compileSdk 36, minSdk 24, Kotlin 2.1.20 and iOS 15.1

  • Bundler resolves the demo Gemfile to activesupport 7.2.3.2 and CocoaPods 1.15.2

  • Master has no required status checks, so the path filters can't leave a PR waiting on a check that never runs

  • The Android and iOS demo builds passed in CI on 3fe8490 (before the RUM commits), so raygun4android 6.2.2 with Java 17 and compileSdk 36, and the new podspec, build

  • Both demos built locally for Android (debug) and the iOS simulator on their new versions, and Metro/expo export bundles both platforms. The bare demo's Android build is the first check of the SDK against Android Gradle Plugin 9

Still to verify:

  • A device check of crash reporting on Android with raygun4android 6
  • A device check of RUM network timing: fetch and XHR requests from the demo, and from an Expo 56+ app, should arrive in the RUM dashboard as network timing events. Unit tests can't show this

Not in this PR

  • The dependabot.yml groups and ignore rules
  • New demo features: a RUM events panel, XHR and native crash triggers, and RUM in ExpoDemo

- `babel-plugin-transform-class-properties` is a Babel 6 plugin that no config loads.
  It pulled in `babel-traverse` 6.26.0, the source of the critical Dependabot alert
- `ts-jest` and `tsconfig.jest.json` are unused, since Jest runs through `babel-jest`.
  `tsconfig.jest.json` has also been invalid since the sdk moved to `nodenext`
- `glob` is a direct dev dependency that nothing imports, and its 11.x release is
  deprecated, so every install printed a warning for it
No job ran `tsc`, so a change that broke the SDK's types could still get a green check.
That's how the uuid 14 bump (#264) merged without anything checking its types.
@velocitysystems
velocitysystems force-pushed the chore/sdk-maintenance branch 4 times, most recently from f923ed9 to 5acc379 Compare September 19, 2026 15:06
Both workflows ran on every `push` and every `pull_request`, so a PR from a branch in this
repo ran each job twice: 8 checks for 4 jobs. Force-pushes also left runs for replaced
commits holding runners ahead of the current one. ExpoDemo wasn't built at all, so
nothing noticed when a dependency update broke it.

- Run on `pull_request`, and on `push` only to master
- Cancel a PR's in-progress runs when a newer commit arrives. Each push to master gets its
  own concurrency group, keyed by commit SHA, because GitHub cancels a pending run when a
  newer run joins the same group; this way every master commit gets a complete run
- Only run each workflow when its files change: SDK CI for `sdk/`, Demo CI for `sdk/` and
  `demo/`, Expo Demo CI for `sdk/` and `ExpoDemo/`, each plus its own workflow file. Docs
  and config changes no longer start a macOS build
- Add Expo Demo CI, which installs the SDK and ExpoDemo, runs `expo prebuild`, and builds
  a debug Android app on Ubuntu and an iOS simulator app on macOS 26 with Xcode 26.6, as
  Expo SDK 56 and later need Xcode 26.4 or later
- Check formatting with `prettier --check` inside `sdk-checks`, and drop the separate
  job and its third-party action. Prettier is now a pinned dev dependency (3.9.8), so
  CI no longer picks up whatever version is latest
- Add `sdk/.prettierignore` for `dist/`. The check now runs from `sdk/`, and Prettier
  only reads ignore files from the directory it runs in, so the root `.gitignore`
  entry for `sdk/dist/` doesn't apply there; a local build would fail the check
- Limit the workflow token to `contents: read`

Master has no required status checks, so a workflow skipped by its path filter can't
leave a PR waiting on a check that never runs.
raygun4android 6 declares `minCompileSdk=36`, so host apps must compile against Android
SDK 36 or higher. React Native 0.81 is the oldest release whose defaults do, which sets
the new floor for the SDK.

- raygun4android 5.2.1 → 6.2.2. Keep the kotlin-stdlib exclusion: 6.2.2 declares stdlib
  2.4.10, which the Kotlin compilers in React Native 0.81-0.87 can't read
- Fallback compileSdk 35 → 36 and minSdk 23 → 24, matching React Native 0.81's defaults
- Drop the library's `targetSdk` and `buildToolsVersion`, which have no effect on an
  Android library under AGP 8
- Java 11 → 17, which React Native 0.81+ already requires
- Timber 4.7.1 → 5.0.1, the version raygun4android already resolves to
- Replace the deprecated `hasActiveCatalystInstance()` with `hasActiveReactInstance()`
`s.source` pointed at the `kerwin/refactory/storage` branch of a personal fork
(`hunteva/raygun4reactnative`), so anything resolving the pod from its source got that
branch rather than this repo's release.

- Point `s.source` at MindscapeHQ/raygun4reactnative, at the release's `v<version>` tag
- Take the iOS minimum from React Native's `min_ios_version_supported` (15.1 for
  React Native 0.81+) instead of the stale 12.0
- Use `install_modules_dependencies` instead of depending on `React-Core` directly,
  as React Native's library template does
- Remove the `RCTConvert` and `RaygunCrashReportConverter` imports from
  `RaygunNativeBridge.m`; nothing in the file uses either
- `prepublish` doesn't run on `npm publish` from npm 7 on, so a publish shipped whatever
  `dist/` was on the publishing machine, however stale. Replace it with `prepare`, which
  runs on `npm pack` and `npm publish`, and on a local `npm install` or `npm ci` as
  `prepublish` did, so ExpoDemo, which uses the SDK through `file:../sdk` and
  `dist/index.js`, still gets a build. It clears `dist/` first, because `tsc` never
  removes output for deleted sources and a 1.x `dist/` would otherwise ship its leftovers
- Installing ExpoDemo now runs that build inside `../sdk`, which needs the SDK's dev
  dependencies, so ExpoDemo's README installs the SDK first, as the bare demo's does
- Without a `files` allowlist, the 1.7.1 tarball shipped `__tests__`, `__mocks__`,
  `babel.config.js` and `eslint.config.mjs` to customers. List the runtime files
  instead. Android is listed file by file so a local `android/build/` can't be packed
- Delete `.npmignore`, which npm ignores once `files` is set

`npm pack --dry-run` now lists 34 files: `dist/`, the Android sources and Gradle files,
the iOS sources, the podspec, `react-native.config.js`, `package.json` and the README.
The SDK didn't declare which React Native versions it supports, so package managers
couldn't warn apps that fall below it. raygun4android 6 makes React Native 0.81 the
minimum, and these ranges come from what React Native 0.81 itself declares.

- `react-native >=0.81.0`
- `react >=19.1.0`, React Native 0.81's React requirement. Lower bounds only, so a
  future React or React Native major doesn't make npm refuse the install
- `engines.node >=20.19.4`, React Native 0.81's Node requirement
The README still listed React Native `^0.60.0` and async-storage `^1.13.3`, and told
Android users to declare two services that no longer exist.

- Replace the requirements with the minimums this branch sets: React Native 0.81,
  React 19.1, async-storage 1.13-3.x as a peer dependency, Android compileSdk 36 and
  minSdk 24, iOS 15.1, Expo SDK 54
- Install async-storage alongside the SDK, now that it's a peer dependency
- Remove the Android step. It declared `CrashReportingPostService` and `RUMPostService`,
  which raygun4android replaced with WorkManager workers; autolinking needs nothing more
- Remove the `platform :ios, '10.0'` Podfile line, below the new iOS minimum
- Replace the manual integration steps with a short troubleshooting note. Autolinking
  covers React Native 0.81+, and the manual Android steps named the wrong project
- Fix the Expo iOS section, which ran `npx expo run:android`, and install async-storage
  with `npx expo install` so Expo picks a compatible version
- RELEASING.md: the version lives in `sdk/package.json`, not `src/package.json`, and the
  release tag must be `v<version>` for the podspec's `s.source`
- CHANGELOG.md: Expo SDK 55 is React Native 0.83, not 0.81
Both warnings now print on every CI run.

- Prettier 3 deprecates `jsxBracketSameLine`; `bracketSameLine` is its replacement and
  formats the same way
- eslint-plugin-react warns when the React version isn't set. Set it to 19.1, the oldest
  React in the peer dependency range. `"detect"` isn't an option: it calls
  `context.getFilename()`, which ESLint 10 removed, and eslint-plugin-react 7.37.5
  crashes
The demo's Gemfile allowed activesupport 6.1.7.5 and up, which covers versions with
three moderate advisories (GHSA-2j26-frm8-cmj9, GHSA-cg4j-q9v8-6v38 and
GHSA-89vf-4333-qx8v). 7.2.3.1 is the first fixed release below 8, and CocoaPods
requires activesupport below 8.

activesupport 7.2 needs Ruby 3.1 or later, so the Ruby floor rises from 2.6.10 to 3.1.0.
Bundler resolves the Gemfile to activesupport 7.2.3.2 and CocoaPods 1.15.2.

CI runs `pod install` without Bundler, so it doesn't exercise this file. React Native
0.87's template Gemfile still has the old floor, so the demo rebuild needs to keep this.
The MIT license requires its notice to be included with copies of the software, but the
published package has never contained it: the license file is `LICENSE-MIT` at the repo
root, and the package is published from `sdk/`. `sdk/package.json` already names the
file `LICENSE` (`licenseFilename`), and npm always packs a `LICENSE` file.

Add `sdk/LICENSE` with the same text as `LICENSE-MIT`, one line per paragraph rather
than hard-wrapped.
The RUM monitor used `uuidv4()` only to key an in-memory map that pairs each request's
open, send and response callbacks; the ID never leaves the process. Keying the map on the
request itself does the same job. A `WeakMap` also lets a request that is opened but never
completed be collected, rather than holding its entry for the life of the app.

This drops `uuid`, the SDK's last runtime dependency. uuid 14 (#264) only publishes an
ES module through package `exports`, with no `main`, so apps whose Metro doesn't read
`exports` would fail to bundle the SDK. It also calls `crypto.randomUUID` without
checking that `crypto` exists, which would throw on each monitored request once network
monitoring works again.

Also remove `uuid` from Jest's `transformIgnorePatterns`, which only listed it so Jest
would transform its ES module build.
Real User Monitoring has sent no network timing events on React Native 0.80 or later since
1.6.0, and logged nothing about it. The SDK loaded React Native's private XHRInterceptor
from one of two paths: `react-native/src/private/inspector/XHRInterceptor`, which only
existed in React Native 0.79, or `react-native/Libraries/Network/XHRInterceptor`, which
0.79 removed. When neither loaded, it silently fell back to an interceptor that did
nothing. React Native 0.87 no longer exports `./src/*` at all, so correcting the path
wouldn't last.

- Add `NetworkInterceptor.ts`, which wraps `XMLHttpRequest.prototype.open` and `send`
  itself and reports the request when it completes. React Native's `fetch()` is built on
  XMLHttpRequest, so fetch requests are captured too. Callback errors are logged instead
  of reaching the app's request. The callbacks carry only the method, the URL and the
  request, which is all the monitor uses, so the response body is never read
- Wire it into `RealUserMonitor`, and log a warning if XMLHttpRequest isn't available
  rather than failing silently
- Name network events with the method upper-cased and without the query string and
  fragment, as raygun4js, raygun4android and raygun4apple do. The query string can carry
  tokens, and both would otherwise split one endpoint into several names. Before 1.6.0,
  when network timing last worked, the full URL was sent
- Delete `MaybeNewXHRInterceptorModule.ts` and `MaybeOldXHRInterceptorModule.ts`
- Add tests for the interceptor and for the monitor: completed requests become network
  timing events, responses pair with their own requests, ignored URLs are skipped, names
  are normalised, and nothing is intercepted when network monitoring is disabled. The two
  tests that expect events fail against the old code

Expo SDK 56 and later replace the global `fetch` with a native implementation that doesn't
use XMLHttpRequest, so this doesn't capture `fetch()` calls in those apps unless they set
`EXPO_PUBLIC_USE_RN_FETCH=1`.
Expo SDK 56 and later replace the global `fetch` with `expo/fetch`, which makes requests
through a native module rather than XMLHttpRequest. So the XMLHttpRequest interceptor
alone missed every `fetch()` call in those apps, unless they set
`EXPO_PUBLIC_USE_RN_FETCH=1`. Expo SDK 54 and 55 don't replace `fetch`.

- Wrap the global `fetch` as well, reporting each call when it settles. A fetch that
  rejects or throws is reported too, as a failed XMLHttpRequest is, and the error still
  reaches the caller
- Skip XMLHttpRequests opened while a `fetch` call is running. React Native's own `fetch`
  (whatwg-fetch) creates, opens and sends its XMLHttpRequest synchronously inside that
  call, so without this each fetch would be reported twice on React Native and Expo 54-55
- Expo's global `fetch` is a lazy property with a setter, so replacing it works there too

Tests cover resolved, rejected and synchronously throwing fetches, Request-like inputs, a
React Native-style fetch being reported once rather than twice, and interception when only
`fetch` is available.
The bare demo was on React Native 0.84.1, with a native layer older than even the 0.84
template: an Objective-C AppDelegate, and DefaultReactNativeHost and SoLoader in
MainApplication. Its tsconfig extended a path that @react-native/typescript-config no
longer exports, so `tsc` couldn't run.

- Regenerate `android/` and `ios/` from the React Native 0.87.1 template, keeping the one
  customisation: the `Raygun4ReactNativeDemo` module name. The template's lower Kotlin
  (2.2.0) now exercises the SDK's kotlin-stdlib exclusion
- Take the template's config files (Babel, Metro, Jest, TypeScript, ESLint, Prettier,
  Watchman, Bundler, `.gitignore`) and Gemfile, keeping this branch's Ruby 3.1 and
  activesupport floor
- Move react-native to 0.87.1 with its tooling, and the demo's libraries to their latest:
  React Navigation 7.4.1 and 7.19.2, react-native-screens 4.28.0,
  react-native-safe-area-context 5.10.0, and async-storage 3.1.1, which exercises the
  SDK's support for v3
- Keep @react-native-community/checkbox on 0.5.20. 0.6.0's `codegenConfig` points at a
  `js` directory the package doesn't ship, so iOS codegen fails. 0.5.20 defines
  BuildConfig fields, which Android Gradle Plugin 9 only generates when a module turns
  them on, so the root `build.gradle` turns them on for that module
- Regenerate `package-lock.json` and `Podfile.lock`, which recorded the SDK as 1.6.0

The app code (`App.tsx`, `screens/`, `utils/`) is unchanged. Built locally: an Android
debug build (AGP 9.2.1, compileSdk 37) and an iOS simulator build, plus Metro release
bundles for both platforms. `tsc` now runs and reports 9 type-only errors in the screens,
left alone because fixing them changes the demo code.
ExpoDemo was on Expo SDK 55 and couldn't start or bundle: #256 moved it to TypeScript 7,
which has no JavaScript API, and Expo's CLI reads `tsconfig.json` through that API.

- Run `npx expo install expo@~57.0.24` and `npx expo install --fix`: Expo 57.0.24, React
  Native 0.86.3, TypeScript 6.0.3, and every Expo package on its SDK 57 version
- Install react-native-worklets, a required peer dependency of react-native-reanimated 4
- Remove `newArchEnabled` from `app.json`, which SDK 57's config schema rejects, as the
  New Architecture is always on. `expo install` added the `expo-status-bar` config plugin
- Regenerate `package-lock.json`, whose SDK entry recorded 1.6.0

The app code is unchanged. `expo install --check` and `tsc` are clean. Expo Doctor passes
20 of 21 checks; the other flags the SDK's own `../sdk/node_modules`, which native
autolinking doesn't use and the Metro config blocks. Built locally: `expo export` for both
platforms, and an Android debug build and iOS simulator build after `expo prebuild`.
With the RN 0.87 tsconfig, `tsc` could run on the bare demo and reported 9 errors. All are
type-only; none changes what the demo does.

- Pass `e as Error` to `sendError` in the four `catch` blocks, whose variables are
  `unknown`
- Use `undefined` instead of `null` for the breadcrumb's `level` and the user's
  `fullName`, which the SDK types as optional strings. `recordBreadcrumb` and `setUser`
  strip `null` fields before applying defaults, so both values end up the same
- Give `@react-native-community/checkbox` a component type. Its typings declare a class
  that React 19's JSX types reject, and the package exports no props type
- Return `null` from `completedImageLoad`, which is called inside JSX; it rendered nothing
  before and still does
- Delete `plugins/withRaygunAndroid.js` and its `app.json` entry. It added
  `CrashReportingPostService` and `RUMPostService` to the Android manifest, but
  raygun4android replaced those services with WorkManager workers, so nothing ever started
  them. The SDK's README stopped asking for them in this branch
- Remove `@react-navigation/native` and `@react-navigation/bottom-tabs`. The app doesn't
  import them, and Expo Router hasn't needed them since SDK 56
- Remove the `reset-project` script, whose `scripts/reset-project.js` doesn't exist, and
  the `test` script with its Jest setup (`jest`, `jest-expo`, `@types/jest`), as there are
  no tests

The app code is unchanged. `expo install --check` and `tsc` are clean, `expo export`
bundles both platforms, and a fresh `expo prebuild` has no Raygun services in the
manifest.
The bare demo depended on `file:raygun4reactnative-<version>.tgz`, a tarball that
`.gitignore` excludes, so following its README on a fresh clone failed with ENOENT. Only
the SDK's `build_pack_1` and `build_demo_2` scripts, which CI ran, created it. Every SDK
change also changed the tarball's integrity hash in the demo's lockfile.

- Depend on `file:../sdk`, as ExpoDemo does. Installing it runs the SDK's `prepare` build
- Point Metro at `../sdk`, block the SDK's own `node_modules`, and resolve the SDK's
  imports from the demo's `node_modules`, as ExpoDemo's Metro config does
- Update the README: `npm install` replaces `npm install --install-links`
- CI installs the SDK and the demo with `npm ci` instead of packing and copying a tarball
- Remove the SDK's `builder`, `build_run`, `build_pack_1`, `build_demo_2` and `run_demo_3`
  scripts, and the `copyfiles` and `run-script-os` dev dependencies only they used

Checked on a clean install: `npm ci`, `tsc`, Metro release bundles for both platforms,
`pod install`, and Android debug and iOS simulator builds.
The SDK's iOS sources produced 8 compiler warnings in every app build. None changed
behaviour; they came from declarations and code nothing uses.

- `RaygunNativeBridge.h` declared `viewStartedLoading:atTime:` and
  `viewFinishedLoading:atTime:`, which don't exist. The bridge implements and registers
  the notification handlers `viewStartedLoading:` and `viewFinishedLoading:`
- `UIViewController+ReactNativeRaygunRUM.h` declared `loadViewCapture`,
  `viewDidLoadCapture`, `viewWillAppearCapture:` and `viewDidAppearCapture:`, which don't
  exist either. `+load` swizzles the `...CaptureReactNative` methods the category defines
- Remove `ksdl_imageNamed`, which nothing calls, and the `<mach-o/dyld.h>` include only it
  used
- Declare `processStartTime(void)`, as C requires for a function with no parameters

The demo's iOS simulator build now compiles the SDK with no warnings.
`tsc --noEmit` used the SDK's tsconfig, whose `include` is `src/` alone, so a type error
in `__tests__` passed CI: Jest strips types through `babel-jest`, and ESLint only lints
`src/`. A deliberate error in a test file exited 0 before this change, and fails now.

- Add `tsconfig.test.json`, extending the SDK's config with `src/`, `__tests__/` and
  `__mocks__/`, and with Node's types for the globals the tests replace
- Point CI's type-check step at it
- Type the `fetch` and `sendError` mocks the existing tests install, so the calls they
  record keep their types instead of widening to an empty tuple
- Add a CI badge to both READMEs, as raygun4flutter does
- The Native Crash Reporting section said to set `disableNativeCrashReporting` to `false`
  to disable it, in two places. The provider starts the native SDKs when the flag is
  false, so disabling them needs `true`
- Fix two table-of-contents anchors that no longer match their headings: the
  `sendRUMTimingEvent` parameter is `durationMs`, and `setUser` takes `User | null`
- Fix three typos

Checked every anchor in the SDK README against the heading it points at, and that the
badge URL responds.
@velocitysystems
velocitysystems force-pushed the chore/sdk-maintenance branch 4 times, most recently from 8f20994 to 08a1161 Compare September 21, 2026 11:13
raygun4android requires okhttp 5, and it is the only module in a React Native app that
asks for it. Gradle's conflict resolution raises `okhttp` to 5.x and leaves
`okhttp-urlconnection` on the 4.x that React Native declares, because nothing asks for a
newer one. The two are released as a pair: `JavaNetCookieJar` in 4.x calls
`okhttp3.internal.Util`, which 5.x removed, so the app stops with a NoClassDefFoundError
when React Native's cookie jar reads a stored cookie. The first request after a clean
install works and one after a restart does not, which makes it look intermittent.

Add the okhttp platform to the SDK. It constrains every okhttp artifact in the host app to
one version and adds nothing to the dependency graph. The version has to match the okhttp
that raygun4android requires, so it needs revisiting whenever that changes.

The split is older than this branch: raygun4android 5.2.1, which master uses, requires
okhttp 5.3.0, and that release has no `okhttp3.internal.Util` either. Reported upstream as
MindscapeHQ/raygun4android#324, which is where it belongs.

Checked on an Android emulator with both demos: the app stops with the constraint removed,
and survives the same steps with it in place, with neither demo declaring anything itself.
Both demos sent every request with `fetch`, and ExpoDemo ran with Real User Monitoring
off, so two of the three paths the SDK intercepts were never exercised outside the unit
tests: a request made with XMLHttpRequest, which libraries such as axios use, and Expo SDK
56's `fetch`, which is native and does not use XMLHttpRequest.

- Add a "Send XHR Request" section to the demo's RUM screen. The URL carries a query
  string and a fragment, so the name RUM reports shows they are removed
- Turn Real User Monitoring on in ExpoDemo, and give it a fetch button and an XHR button

The API key placeholders are unchanged, so both demos still need one before they report.

Checked on an Android emulator and an iOS simulator: each path reports one network event,
and the five concurrent requests stay one name with five requests.
2.0.0 because this release raises the minimum to React Native 0.81, Android compileSdk
36 and iOS 15.1, and makes react, react-native and async-storage peer dependencies.

- Bump `sdk/package.json` and `sdk/package-lock.json` to 2.0.0
- Add the 2.0.0 `CHANGELOG.md` entry, with the breaking changes listed first

It comes last on the branch so that the commit is the state the release publishes. Both
demos consume the SDK from `file:../sdk`, so neither records a version to bump here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant