Skip to content

[RN 0.88] Replace deep RN imports with public API #743

Open

Description

@leotm

Sub-issue of

the strict TS API breaks packages with deep imports into RN internals

https://github.com/search?q=repo%3AAppAndFlow%2Freact-native-safe-area-context%20%22react-native%2FLibraries%2FTypes%2FCodegenTypes%22&type=code

https://github.com/search?q=repo%3AAppAndFlow%2Freact-native-safe-area-context+%22react-native%2FLibraries%2FUtilities%2FcodegenNativeComponent%22&type=code

not resolvable by consumers (with moduleResolution: "bundler") which fails type resolution

so they need to use public API exports since RN 0.88, e.g.

import type { CodegenTypes } from 'react-native'; // CodegenTypes.Double, CodegenTypes.DirectEventHandler
import { codegenNativeComponent } from 'react-native';

then also

SafeArea.types.ts
update InstanceType<typeof NativeSafeAreaView> to Component<NativeSafeAreaViewProps>

SafeAreaContext.tsx
add explicit type (e: InsetChangedEvent)

example patch
diff --git a/src/SafeArea.types.ts b/src/SafeArea.types.ts
index d3d23b6..a25d3b9 100644
--- a/src/SafeArea.types.ts
+++ b/src/SafeArea.types.ts
@@ -1,6 +1,6 @@
 import type * as React from 'react';
+import type { Component } from 'react';
 import type { NativeSyntheticEvent, ViewProps } from 'react-native';
-import NativeSafeAreaView from './specs/NativeSafeAreaView';
 
 export type Edge = 'top' | 'right' | 'bottom' | 'left';
 export type EdgeMode = 'off' | 'additive' | 'maximum';
@@ -42,6 +42,4 @@ export interface NativeSafeAreaViewProps extends ViewProps {
   edges?: Edges;
 }
 
-export type NativeSafeAreaViewInstance = InstanceType<
-  typeof NativeSafeAreaView
->;
+export type NativeSafeAreaViewInstance = Component<NativeSafeAreaViewProps>;
diff --git a/src/SafeAreaContext.tsx b/src/SafeAreaContext.tsx
index ed192d7..caed333 100644
--- a/src/SafeAreaContext.tsx
+++ b/src/SafeAreaContext.tsx
@@ -119,7 +119,7 @@ export function SafeAreaListener({
     <NativeSafeAreaProvider
       {...others}
       style={[styles.fill, style]}
-      onInsetsChange={(e) => {
+      onInsetsChange={(e: InsetChangedEvent) => {
         onChange({
           insets: e.nativeEvent.insets,
           frame: e.nativeEvent.frame,
diff --git a/src/specs/NativeSafeAreaProvider.ts b/src/specs/NativeSafeAreaProvider.ts
index 5e6974e..b106412 100644
--- a/src/specs/NativeSafeAreaProvider.ts
+++ b/src/specs/NativeSafeAreaProvider.ts
@@ -1,27 +1,23 @@
-import type {
-  DirectEventHandler,
-  Double,
-} from 'react-native/Libraries/Types/CodegenTypes';
-import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
-import type { ViewProps, HostComponent } from 'react-native';
+import type { CodegenTypes, ViewProps, HostComponent } from 'react-native';
+import { codegenNativeComponent } from 'react-native';
 
 export type Event = Readonly<{
   insets: Readonly<{
-    top: Double;
-    right: Double;
-    bottom: Double;
-    left: Double;
+    top: CodegenTypes.Double;
+    right: CodegenTypes.Double;
+    bottom: CodegenTypes.Double;
+    left: CodegenTypes.Double;
   }>;
   frame: Readonly<{
-    x: Double;
-    y: Double;
-    width: Double;
-    height: Double;
+    x: CodegenTypes.Double;
+    y: CodegenTypes.Double;
+    width: CodegenTypes.Double;
+    height: CodegenTypes.Double;
   }>;
 }>;
 
 export interface NativeProps extends ViewProps {
-  onInsetsChange?: DirectEventHandler<Event>;
+  onInsetsChange?: CodegenTypes.DirectEventHandler<Event>;
 }
 
 export default codegenNativeComponent<NativeProps>(
diff --git a/src/specs/NativeSafeAreaView.ts b/src/specs/NativeSafeAreaView.ts
index 0ab6adf..b031d12 100644
--- a/src/specs/NativeSafeAreaView.ts
+++ b/src/specs/NativeSafeAreaView.ts
@@ -1,9 +1,8 @@
-import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
-import type { WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
 import type { ViewProps, HostComponent } from 'react-native';
+import { codegenNativeComponent } from 'react-native';
 
 export interface NativeProps extends ViewProps {
-  mode?: WithDefault<'padding' | 'margin', 'padding'>;
+  mode?: 'padding' | 'margin';
   edges?: Readonly<{
     top: string;
     right: string;

Activity

  1. changed the title [-][0.88] Replace deep RN imports with public API[/-] [+][RN 0.88] Replace deep RN imports with public API[/+] on Jul 21, 2026
  2. janicduplessis commented on Aug 3, 2026

    @janicduplessis
    Collaborator

    I am thinking of releasing a major version with new arch only support + modern imports that would be compatible with RN 0.82+

  3. leotm commented on Aug 6, 2026

    @leotm
    Author

    sounds like a plan ^ both warrant a new maj ver, even tho RN 0.82 is unsupported

  4. brunozampirom commented on Sep 16, 2026

    @brunozampirom

    Checked when the public API actually landed, since the title targets 0.88.

    CodegenTypes and codegenNativeComponent are re-exported from react-native starting in 0.80.0. I compile-tested the three symbols this repo needs (Double, WithDefault, DirectEventHandler) plus codegenNativeComponent with tsc --noEmit:

    RN result
    0.78.0 TS2305: has no exported member
    0.79.0 TS2305: has no exported member
    0.79.6 TS2305: has no exported member
    0.80.0 compiles
    0.81.5 compiles

    So the RN 0.82+ floor mentioned above already clears this with room to spare. It is still breaking for anyone typechecking below 0.80, since peerDependencies is currently *, so it does belong in the major. It just is not the constraint that sets the floor. The new arch requirement is.

    Currently 6 occurrences across 4 files: 5 imports in src/specs/ and one require in src/__tests__/InitialWindow-test.tsx.

    Happy to open the PR if that helps.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions