Contributing
April 30, 2026 · View on GitHub
Prerequisites
Required (all platforms)
- nodenv with Node 22 — Stripe's standard Node version manager. The repo includes a
.node-versionfile, so nodenv selects the right version automatically.
Not using nodenv? Install Node 22 via nodejs.org or your preferred method.nodenv install # installs the pinned version if not already present - Yarn 1.x — install if not already present:
npm install --global yarn@1 - Watchman (macOS — required for Metro file watching):
brew install watchman
iOS
- Xcode with iOS simulator runtimes installed
- CocoaPods:
brew install cocoapods - SwiftLint (required for pre-commit hooks):
brew install swiftlint
Android
- Android Studio with Android SDK installed
- Open Android Studio via terminal to pick up your shell environment:
open /Applications/Android\ Studio.app
- Open Android Studio via terminal to pick up your shell environment:
- JDK 17+ (Android Gradle Plugin requirement). Homebrew OpenJDK works:
brew install openjdk@17
Getting started
1. Clone and bootstrap
git clone https://github.com/stripe/stripe-react-native.git
cd stripe-react-native
yarn bootstrap
yarn bootstrap runs three steps:
yarn example— installs JS dependencies for the example appyarn— installs JS dependencies for the SDK itself (and runsprepare, which builds the TypeScript)yarn pods— runspod installfor the iOS example app
If pod install fails with a CDN error, retry — CocoaPods CDN can be flaky:
cd example/ios && pod install --repo-update
2. Run the example app
The example app uses a remote demo backend at rigorous-heartbreaking-cephalopod.stripedemos.com, so no local server setup is required. If you need to modify the backend (e.g. add a new endpoint), update the sandbox app at sandbox-apps/rigorous-heartbreaking-cephalopod and deploy to stripedemos.com.
iOS:
# Terminal 1: Start Metro bundler
yarn example start
# Terminal 2: Build and run on simulator
yarn example ios
Or open example/ios/example.xcworkspace in Xcode and run the ReactTestApp scheme.
Android:
# Terminal 1: Start Metro bundler
yarn example start
# Terminal 2: Build and run on emulator/device
yarn example android
Or open example/android in Android Studio and run the app from there.
Editing native code
- iOS: Open
example/ios/example.xcworkspacein Xcode. Find SDK source files atPods > Development Pods > stripe-react-native. - Android: Open
example/androidin Android Studio. Find SDK source files underreactnativestripesdk. - TypeScript: Edit files in
src/andexample/with your editor of choice. Metro picks up JS/TS changes fromsrc/directly, but type definitions are served fromlib/. If you change the SDK's public API and your editor shows stale types, runyarnat the repo root to rebuildlib/.
Tests
TypeScript unit tests
yarn test
iOS native unit tests
yarn test:unit:ios
Android native unit tests
yarn test:unit:android
E2E tests (Maestro)
We use Maestro for end-to-end testing. Install it first:
brew tap mobile-dev-inc/tap
brew install maestro
Then build and run the example app, and run the tests:
# Build the example app first
yarn run-example-ios # or: yarn run-example-android
# Run all e2e tests
yarn test:e2e:ios # or: yarn test:e2e:android
# Run a single test
yarn test-ios ./e2e-tests/ios-only/financial-connections-token.yml
If Maestro can't find a device, create one:
maestro start-device --platform=ios --os-version 18
Linting and formatting
Pre-commit hooks (via Husky) automatically run lint, typecheck, and formatting on every commit. You can also run them manually:
yarn lint # ESLint
yarn typescript # TypeScript type-check
yarn format:android:check # Kotlin formatting (spotless)
yarn format:android:write # Auto-fix Kotlin formatting
yarn format:ios:check # SwiftLint
yarn format:ios:write # Auto-fix Swift formatting (changed files only)
To fix ESLint issues:
yarn lint --fix
Commit message convention
We follow the conventional commits specification:
fix: bug fixes, e.g. fix crash due to deprecated method.feat: new features, e.g. add new method to the module.refactor: code refactor, e.g. migrate from class components to hooks.docs: changes to documentation, e.g. add usage example for the module.test: adding or updating tests, e.g. add integration tests using Maestro or native unit tests.chore: tooling changes, e.g. change CI config.
Updating native SDKs
The React Native SDK depends on underlying native iOS and Android SDKs. To update:
iOS: Update stripe_version in stripe-react-native.podspec, then run yarn update-pods.
Android: Update StripeSdk_stripeVersion in android/gradle.properties.
Changing the public APIs
The public API is everything exported from src/index.tsx.
Important: After you make changes, run yarn api-extractor:update.
In-development (not yet public) APIs
- Don't export from
src/index.tsx. - Exception - if a public type must reference it:
- Tag it with
@internal. - Teel free to also mark with e.g.
@CheckoutSessionsPrivatePreviewfor easy grepping later.
- Tag it with
/**
* @CheckoutSessionsPrivatePreview
* @internal
*/
export type CheckoutSetupParams = { ... }
Private Preview / Public Preview APIs
- Export from
src/index.tsx. - Use
@MyFeaturePrivatePreview/@MyFeaturePublicPreview.
/**
* @CheckoutSessionsPrivatePreview
*/
export type CheckoutSetupParams = { ... }
Maintaining the Stripe old-architecture patch
We ship patches/old-arch-codegen-fix.patch so that the library builds on React-Native >= 0.74 in the old architecture (it converts EventEmitter properties into callback functions so code-gen doesn't fail).
When to update the patch
The patch needs to be updated when:
- You modify
src/specs/NativeStripeSdkModule.tsand add/remove/change EventEmitter properties - You upgrade dependencies that might affect the TurboModule interface
- The patch fails to apply during testing or CI
How to update the patch
-
Make your changes to the source code in
src/specs/NativeStripeSdkModule.ts -
Create a backup of the original file:
cp src/specs/NativeStripeSdkModule.ts src/specs/NativeStripeSdkModule.ts.orig -
Apply the old-arch compatible changes:
- Remove the
EventEmitterimport from the imports section - Convert all
EventEmitterproperties to callback function methods - For example, change:
To:onConfirmHandlerCallback: EventEmitter<{ paymentMethod: UnsafeObject<PaymentMethod.Result>; shouldSavePaymentMethod: boolean; }>;onConfirmHandlerCallback( callback: (event: { paymentMethod: UnsafeObject<PaymentMethod.Result>; shouldSavePaymentMethod: boolean; }) => void ): void;
- Remove the
-
Generate the new patch:
diff -u src/specs/NativeStripeSdkModule.ts.orig src/specs/NativeStripeSdkModule.ts > patches/old-arch-codegen-fix.patch -
Test the patch:
# Test that the patch applies cleanly git stash # stash your changes patch -p0 < patches/old-arch-codegen-fix.patch # Verify the file looks correct git stash pop # restore your changes -
Commit the updated patch:
git add patches/old-arch-codegen-fix.patch git commit -m "chore: update old-arch codegen fix patch"
Scripts reference
| Script | Description |
|---|---|
yarn bootstrap | Install all dependencies and pods |
yarn test | Run TypeScript unit tests (Jest) |
yarn test:unit:ios | Run iOS native unit tests (xcodebuild) |
yarn test:unit:android | Run Android native unit tests (Gradle) |
yarn test:e2e:ios | Run iOS e2e tests (Maestro) |
yarn test:e2e:android | Run Android e2e tests (Maestro) |
yarn typescript | Type-check with TypeScript |
yarn lint | Lint with ESLint |
yarn example start | Start Metro bundler |
yarn example ios | Run example app on iOS simulator |
yarn example android | Run example app on Android emulator |
yarn run-example-ios | Build and run iOS example (iPhone 16 Pro Max) |
yarn run-example-android | Build and run Android example |
yarn format:android:check | Check Kotlin formatting |
yarn format:android:write | Fix Kotlin formatting |
yarn format:ios:check | Check Swift formatting (SwiftLint) |
yarn format:ios:write | Fix Swift formatting (changed files) |