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-version file, so nodenv selects the right version automatically.
    nodenv install   # installs the pinned version if not already present
    
    Not using nodenv? Install Node 22 via nodejs.org or your preferred method.
  • 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
  • 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:

  1. yarn example — installs JS dependencies for the example app
  2. yarn — installs JS dependencies for the SDK itself (and runs prepare, which builds the TypeScript)
  3. yarn pods — runs pod install for 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.xcworkspace in Xcode. Find SDK source files at Pods > Development Pods > stripe-react-native.
  • Android: Open example/android in Android Studio. Find SDK source files under reactnativestripesdk.
  • TypeScript: Edit files in src/ and example/ with your editor of choice. Metro picks up JS/TS changes from src/ directly, but type definitions are served from lib/. If you change the SDK's public API and your editor shows stale types, run yarn at the repo root to rebuild lib/.

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. @CheckoutSessionsPrivatePreview for easy grepping later.
/**
 * @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.ts and 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

  1. Make your changes to the source code in src/specs/NativeStripeSdkModule.ts

  2. Create a backup of the original file:

    cp src/specs/NativeStripeSdkModule.ts src/specs/NativeStripeSdkModule.ts.orig
    
  3. Apply the old-arch compatible changes:

    • Remove the EventEmitter import from the imports section
    • Convert all EventEmitter properties to callback function methods
    • For example, change:
      onConfirmHandlerCallback: EventEmitter<{
        paymentMethod: UnsafeObject<PaymentMethod.Result>;
        shouldSavePaymentMethod: boolean;
      }>;
      
      To:
      onConfirmHandlerCallback(
        callback: (event: {
          paymentMethod: UnsafeObject<PaymentMethod.Result>;
          shouldSavePaymentMethod: boolean;
        }) => void
      ): void;
      
  4. Generate the new patch:

    diff -u src/specs/NativeStripeSdkModule.ts.orig src/specs/NativeStripeSdkModule.ts > patches/old-arch-codegen-fix.patch
    
  5. 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
    
  6. Commit the updated patch:

    git add patches/old-arch-codegen-fix.patch
    git commit -m "chore: update old-arch codegen fix patch"
    

Scripts reference

ScriptDescription
yarn bootstrapInstall all dependencies and pods
yarn testRun TypeScript unit tests (Jest)
yarn test:unit:iosRun iOS native unit tests (xcodebuild)
yarn test:unit:androidRun Android native unit tests (Gradle)
yarn test:e2e:iosRun iOS e2e tests (Maestro)
yarn test:e2e:androidRun Android e2e tests (Maestro)
yarn typescriptType-check with TypeScript
yarn lintLint with ESLint
yarn example startStart Metro bundler
yarn example iosRun example app on iOS simulator
yarn example androidRun example app on Android emulator
yarn run-example-iosBuild and run iOS example (iPhone 16 Pro Max)
yarn run-example-androidBuild and run Android example
yarn format:android:checkCheck Kotlin formatting
yarn format:android:writeFix Kotlin formatting
yarn format:ios:checkCheck Swift formatting (SwiftLint)
yarn format:ios:writeFix Swift formatting (changed files)