Skip to content

Add BigInt Support to Java Turbo Module (#56018)#56018

Open
christophpurrer wants to merge 4 commits intofacebook:mainfrom
christophpurrer:export-D95232272
Open

Add BigInt Support to Java Turbo Module (#56018)#56018
christophpurrer wants to merge 4 commits intofacebook:mainfrom
christophpurrer:export-D95232272

Conversation

@christophpurrer
Copy link
Copy Markdown
Contributor

@christophpurrer christophpurrer commented Mar 9, 2026

Summary:

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:

  • Updated NativeSampleTurboModule.js with getBigInt method declaration
  • Added getBigInt Java method in NativeSampleTurboModuleSpec.java
  • Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
  • Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, facebook::react::BigInt is used as the bridging type.
The Java/JNI layer maps this to Java's long type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

Conversion Table

Type Bits Signed Min Max
Java long 64 -9.2 × 10¹⁸ 9.2 × 10¹⁸
C++ int64_t 64 -9.2 × 10¹⁸ 9.2 × 10¹⁸
C++ uint64_t 64 0 1.8 × 10¹⁹
Java BigInteger Arbitrary Unbounded Unbounded

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

Example:

// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg

Reviewed By: sammy-SC

Differential Revision: D95232272

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 9, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented Mar 9, 2026

@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating Diff in D95232272.

christophpurrer added a commit to christophpurrer/react-native-macos that referenced this pull request Mar 10, 2026
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Differential Revision: D95232272
christophpurrer added a commit to christophpurrer/react-native-macos that referenced this pull request Mar 17, 2026
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Differential Revision: D95232272
@meta-codesync meta-codesync Bot changed the title Add BigInt Support to Java Turbo Module Add BigInt Support to Java Turbo Module (#56018) Mar 17, 2026
christophpurrer added a commit to christophpurrer/react-native-macos that referenced this pull request Apr 16, 2026
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Differential Revision: D95232272
christophpurrer added a commit to christophpurrer/react-native-macos that referenced this pull request May 5, 2026
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Reviewed By: sammy-SC

Differential Revision: D95232272
christophpurrer added a commit to christophpurrer/react-native-macos that referenced this pull request May 5, 2026
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Reviewed By: sammy-SC

Differential Revision: D95232272
christophpurrer added a commit to christophpurrer/react-native-macos that referenced this pull request May 5, 2026
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Reviewed By: sammy-SC

Differential Revision: D95232272
christophpurrer added a commit to christophpurrer/react-native-macos that referenced this pull request May 5, 2026
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Reviewed By: sammy-SC

Differential Revision: D95232272
christophpurrer and others added 4 commits May 5, 2026 16:27
Summary:
Pull Request resolved: facebook#56008

This diff adds native BigInt bridging support to React Native's C++ bridging layer.
BigInt is a JavaScript primitive that represents integers with arbitrary precision,
enabling safe handling of 64-bit integers that exceed JavaScript's Number.MAX_SAFE_INTEGER (2^53-1).

This implementation introduces a `facebook::react::BigInt` C++ wrapper class that
internally stores values as `std::variant<int64_t, uint64_t>`, preserving signedness.
The wrapper is constructed from `jsi::BigInt` (checking `isInt64()`/`isUint64()` for
lossless conversion) and provides `toJSBigInt()` for the reverse direction.

A `Bridging<BigInt>` template specialization converts between `jsi::Value` and
`facebook::react::BigInt`, enabling seamless use in Turbo Module method signatures.

Example usage:
```cpp
// In your Turbo Module
BigInt getBigInt(jsi::Runtime &rt, BigInt arg) {
  return arg;  // Receives BigInt from JS, returns BigInt to JS
}
```

```javascript
// In JavaScript
const result = nativeModule.getBigInt(BigInt('9223372036854775807'));
```

## Hey, wait a moment ....
Why are we not simply bridging like this:
```
struct Bridging<int64_t> {
```
or
```
struct Bridging<uint64_t> {
```

??????

Reason: It is very likely that custom implementations are already present in many RN apps > See: https://reactnative.dev/docs/the-new-architecture/custom-cxx-types
```
template <>
struct Bridging<int64_t> {
  // Converts from the JS representation to the C++ representation
  static int64_t fromJs(jsi::Runtime &rt, const jsi::String &value) {
    try {
      size_t pos;
      auto str = value.utf8(rt);
      auto num = std::stoll(str, &pos);
      if (pos != str.size()) {
        throw std::invalid_argument("Invalid number"); // don't support alphanumeric strings
      }
      return num;
    } catch (const std::logic_error &e) {
      throw jsi::JSError(rt, e.what());
    }
  }

  // Converts from the C++ representation to the JS representation
  static jsi::String toJs(jsi::Runtime &rt, int64_t value) {
    return bridging::toJs(rt, std::to_string(value));
  }
};
```

Changelog: [General][Added] - Add BigInt bridging support for Turbo Modules

Differential Revision: D95706781
Summary:
This diff extends the React Native codegen to support BigIntTypeAnnotation.
This type enables Turbo Modules to handle 64-bit integers safely by using
JavaScript BigInt on the JS side and `facebook::react::BigInt` on native C++
platforms (with Java `long` for Android JNI).

Changes:
- Added BigIntTypeAnnotation to CodegenSchema.js
- Added emitBigInt parser function in parsers-primitives.js
- Added TSBigIntKeyword mapping in TypeScript parser
- Updated GenerateModuleH.js for C++ header generation with `BigInt` param/return
  type and `jsi::BigInt` callFromJs return type
- Updated GenerateModuleJavaSpec.js — BigInt maps to 'long' for JNI params
  but throws "not supported" for Java spec generation (not yet supported)
- Updated GenerateModuleJniCpp.js with BigIntKind return type
- Updated Objective-C generators: serializeMethod.js, StructCollector.js,
  serializeConstantsStruct.js, serializeRegularStruct.js
- Updated compatibility check: ErrorFormatting.js, SortTypeAnnotations.js,
  TypeDiffing.js

Example Turbo Module definition:
```javascript
export interface Spec extends TurboModule {
  +getBigInt: (arg: bigint) => bigint;
}
```

Changelog: [General][Added] - Add BigInt Type Support for Turbo Module Code Generation

Differential Revision: D95232267
Summary:
This diff adds BigInt method support to the C++ sample Turbo Module (NativeCxxModuleExample),
demonstrating how to use `facebook::react::BigInt` with the bridging layer.

Changes:
- Added getBigInt method to NativeCxxModuleExample.cpp/.h using
  `facebook::react::BigInt` as the C++ type
- Added getBigInt to NativeCxxModuleExample.js spec
- Added BigIntKind to TurboModule.h for the method dispatch infrastructure
- Updated RCTTurboModule.mm to handle BigIntKind in the iOS TurboModule bridge
- Fixed BigInt rendering in NativeCxxModuleExampleExample.js — JSON.stringify()
  cannot serialize BigInt, so bigint values are now rendered via .toString()

The `facebook::react::BigInt` wrapper class (introduced in the bridging diff)
stores values as `std::variant<int64_t, uint64_t>`, preserving signedness.
The `Bridging<BigInt>` specialization handles conversion to/from `jsi::BigInt`.

Example:
```cpp
BigInt NativeCxxModuleExample::getBigInt(jsi::Runtime& rt, BigInt arg) {
  return arg;
}
```

Changelog: [General][Added] - Add BigInt bridging support for Turbo Modules

Differential Revision: D95232265
Summary:
Pull Request resolved: facebook#56018

This diff adds a getBigInt method to the Java/Kotlin sample Turbo Module,
demonstrating how to use JavaScript BigInt with BigInt bridging on Android.

Changes:
- Updated NativeSampleTurboModule.js with getBigInt method declaration
- Added getBigInt Java method in NativeSampleTurboModuleSpec.java
- Implemented getBigInt in SampleTurboModule.kt using Kotlin's Long type
- Added getBigInt test case in SampleTurboModuleExample.js

On the C++ side, `facebook::react::BigInt` is used as the bridging type.
The Java/JNI layer maps this to Java's `long` type (64-bit signed integer).
JavaScript BigInt values are automatically bridged to/from Java long via the
BigIntKind return type in the JNI bindings.

## Conversion Table
| Type | Bits | Signed | Min | Max |
| --- | --- | --- | --- | --- |
| Java  long | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  int64_t | 64 | ✅ | -9.2 × 10¹⁸ | 9.2 × 10¹⁸ |
| C++  uint64_t | 64 | ❌ | 0 | 1.8 × 10¹⁹ |
| Java  BigInteger | Arbitrary | ✅ | Unbounded | Unbounded |

RESULT -> Any uint64_t value greater than 9,223,372,036,854,775,807 (2⁶³ - 1) cannot be correctly represented in a Java long

## Example:
```java
// Java spec (hand-written, codegen not yet supported for BigInt)
DoNotStrip
public BigInteger getBigInt(BigInteger arg) { return 0; }
```

```kotlin
// Kotlin implementation
override fun getBigInt(arg: BigInteger): BigInteger = arg
```

Reviewed By: sammy-SC

Differential Revision: D95232272
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants