Skip to content

feat(core): Use react-native-quick-base64 for envelope encoding when available#6314

Open
alwx wants to merge 4 commits into
mainfrom
alwx/feature/base64-quick-base64
Open

feat(core): Use react-native-quick-base64 for envelope encoding when available#6314
alwx wants to merge 4 commits into
mainfrom
alwx/feature/base64-quick-base64

Conversation

@alwx

@alwx alwx commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

Adds react-native-quick-base64 as an optional peer dependency of @sentry/react-native. When the package is installed by the consumer, the SDK uses its native JSI base64 encoder (~10x faster than the bundled JS implementation) for envelope payloads on the RNSentry.captureEnvelope hot path. When the package is absent the SDK falls back to the existing base64-js-derived encoder in vendor/base64-js — no behavior change for users who do not opt in.

Changes:

  • New packages/core/src/js/utils/base64.tsencodeToBase64() resolves the encoder once and caches it. Tries require('react-native-quick-base64') first; falls back to base64StringFromByteArray from vendor/base64-js.
  • packages/core/src/js/wrapper.tscaptureEnvelope now calls encodeToBase64(envelopeBytes) instead of base64StringFromByteArray(envelopeBytes) directly.
  • packages/core/package.jsonreact-native-quick-base64 >=3.0.0 added to peerDependencies and marked optional: true in peerDependenciesMeta. No new required deps.
  • CHANGELOG.md — entry under Unreleased / Features.

💡 Motivation and Context

Closes #4884.

💚 How did you test it?

Addded tests!

📝 Checklist

  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing
  • No breaking changes

🔮 Next steps

  • Real-device benchmark on a large envelope (profile / replay) to confirm the headline ~10x figure in our pipeline.
  • Optionally mention react-native-quick-base64 in the Sentry docs as a recommended performance install for users shipping large payloads.

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • feat(core): Use react-native-quick-base64 for envelope encoding when available by alwx in #6314
  • chore(deps): update JavaScript SDK to v10.59.0 by github-actions in #6321
  • chore(deps): bump concurrent-ruby from 1.3.6 to 1.3.7 in /samples/react-native-macos by dependabot in #6327
  • chore(deps): bump undici from 6.24.1 to 6.27.0 by dependabot in #6328
  • chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 by dependabot in #6324
  • fix(ios): [RN 0.87] remove unused React/RCTTextView.h import by cortinico in #6322
  • chore(deps): bump actions/setup-java from 5.2.0 to 5.3.0 by dependabot in #6326
  • chore(deps): bump ruby/setup-ruby from 1.313.0 to 1.314.0 by dependabot in #6325
  • chore(deps): update Android SDK to v8.44.1 by github-actions in #6323

🤖 This preview updates automatically when you update the PR.

alwx added a commit that referenced this pull request Jun 18, 2026
Link to the PR (#6314) instead of the issue, drop the unverified "~10x"
figure (we have not benchmarked locally), and match the terser phrasing
used by the closest analogue (#4874, the TextEncoder envelope entry).
alwx added a commit that referenced this pull request Jun 18, 2026
Link to the PR (#6314) instead of the issue, drop the unverified "~10x"
figure (we have not benchmarked locally), and match the terser phrasing
used by the closest analogue (#4874, the TextEncoder envelope entry).
@alwx alwx force-pushed the alwx/feature/base64-quick-base64 branch from f64591a to 383df08 Compare June 18, 2026 09:34
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor
Fails
🚫 Pull request is not ready for merge, please add the "ready-to-merge" label to the pull request
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 503dd56

alwx added a commit that referenced this pull request Jun 22, 2026
After merging main, the base64 entry ended up under the released
`## 8.15.0` section. Move it back under `## Unreleased` → `### Features`
as flagged by DangerJS on #6314.
@alwx alwx marked this pull request as ready for review June 22, 2026 08:23
Comment thread packages/core/test/utils/base64.test.ts Outdated
Comment thread packages/core/src/js/utils/base64.ts Outdated
/**
* Resolves the base64 encoder once. If the optional peer dependency
* `react-native-quick-base64` is installed, its native JSI encoder is used
* (~10x faster than the pure-JS fallback). Otherwise the bundled JS encoder

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: Is there a reference for the 10x claim?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's true that its not really verifyable, and also depends on a real device that uses it. the claim comes from the original issue but better be removed completely

Comment thread packages/core/src/js/utils/base64.ts
alwx added 2 commits June 22, 2026 11:35
…available

Adds `react-native-quick-base64` as an optional peer dependency. When the
package is installed by the consumer, envelope payloads are base64-encoded
via its native JSI implementation (~10x faster than the bundled JS
encoder). When it is absent, the SDK transparently falls back to the
existing `base64-js`-derived encoder in `vendor/base64-js` — no behavior
change for users who do not opt in.

The encoder is resolved once at first use and cached, so the optional
`require` runs at most once per session. Base64 encoding is on the hot
path of `RNSentry.captureEnvelope` and is most impactful for large
envelopes (profiles, attachments, replays).

Closes #4884.
Link to the PR (#6314) instead of the issue, drop the unverified "~10x"
figure (we have not benchmarked locally), and match the terser phrasing
used by the closest analogue (#4874, the TextEncoder envelope entry).
"react": ">=17.0.0",
"react-native": ">=0.65.0"
"react-native": ">=0.65.0",
"react-native-quick-base64": ">=3.0.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we do not have any peer dependencies other react-native and expo, I am still skeptical on if we should add a dependency for this improvement.
Since RNSentry is a TurboModule and could accept the envelope bytes as binary across JSI on the new architecture what do you think of pursuing our own solution without a new dependency?

Looping @lucas-zimerman for more feedback on this 🙇

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that it's a bit of reinventing the wheel.
Of course, Claude can do it easily but even the first not really working stage of it is already 1000+ lines of code (#6312) and I'm a bit sceptical about the maintenance load and the fact that a verified, well-tested and well-maintained solution which is react-native-quick-base64 works better than either we or Claude can do.
In addition, this is an optional peer dependency, people could still use the old approach if they don't want it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that it's a bit of reinventing the wheel.

I totally agree with that. My concern is that by design we have avoided dependencies (ref1, ref2) even for core functionality.

@antonis antonis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the changes on this PR look good. My main concern is if we should add a dependency since this has been avoided by design in the SDK till now.

alwx added 2 commits June 22, 2026 11:56
After merging main, the base64 entry ended up under the released
`## 8.15.0` section. Move it back under `## Unreleased` → `### Features`
as flagged by DangerJS on #6314.
- Probe the native `fromByteArray` binding once at resolution so a
  broken native module (e.g. autolinking failed) falls through to the
  JS encoder instead of throwing on every `captureEnvelope`.
- Drop the unverified "~10x faster" claim from the JSDoc.
- Replace the sentinel-return test mock with a real base64
  implementation and assert the actual encoded string, so the test
  verifies the encoding output and not just the routing.
- Add a test covering the broken-native-module fallback path.
@alwx alwx force-pushed the alwx/feature/base64-quick-base64 branch from 7cd554d to 503dd56 Compare June 22, 2026 09:56
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.

Use CPP Base64 Encoder for better performance (>10x)

2 participants