FumadocsRN Device Geometry

API Reference

Complete documentation for React Native Device Geometry

API Reference

Complete reference for the react-native-device-geometry library. This library provides direct access to your device's physical display properties including cutouts, corners, metrics, and geometry data.


Core API

DeviceGeometry Class

The main API class providing static methods to interact with device geometry.

getGeometry()

Platform: iOS 9.0+ | Android 9.0+ (API 28)

Fetches a complete snapshot of the device's geometry data including all displays, cutouts, corners, and metrics.

static getGeometry(options?: GeometryOptions): Promise<DeviceGeometryInfo>

Parameters:

Prop

Type

Returns: Promise<DeviceGeometryInfo> - Complete geometry data for all displays

Example - Basic Usage:

import { DeviceGeometry } from 'react-native-device-geometry';

const geometry = await DeviceGeometry.getGeometry();
console.log('Primary display:', geometry.mainDisplay);
console.log('All displays:', geometry.displays);

Example - With Advanced Options:

// Request SVG paths and complex curve data
const geometry = await DeviceGeometry.getGeometry({
  includePaths: true,        // Include SVG path strings
  supportComplex: true       // Include bezier curve data
});

// Use the SVG path for cutout rendering
const cutout = geometry.mainDisplay.cutouts.cutouts[0];
if (cutout.path) {
  console.log('Cutout SVG path:', cutout.path);
}

getDisplayInfo()

Platform: iOS 9.0+ | Android 9.0+ (API 28)

Gets geometry information for a specific display by its ID. Useful for multi-display scenarios.

static getDisplayInfo(displayId: string): Promise<DisplayGeometryInfo | null>

Parameters:

Prop

Type

Returns: Promise<DisplayGeometryInfo | null> - Display info or null if not found

Example:

const geometry = await DeviceGeometry.getGeometry();
const displayId = geometry.displays[0].displayId;

// Get info for specific display
const displayInfo = await DeviceGeometry.getDisplayInfo(displayId);
if (displayInfo) {
  console.log('Display metrics:', displayInfo.metrics);
  console.log('Has cutout:', displayInfo.cutouts.hasCutout);
}

hasCutout()

Platform: iOS 11.0+ | Android 9.0+ (API 28)

Quick check to determine if the device has any display cutouts (notch, punch-hole, Dynamic Island, etc.).

static hasCutout(): Promise<boolean>

Returns: Promise<boolean> - True if device has cutouts

Example - Conditional UI Rendering:

import { DeviceGeometry } from 'react-native-device-geometry';

function AdaptiveHeader() {
  const [hasCutout, setHasCutout] = useState(false);

  useEffect(() => {
    DeviceGeometry.hasCutout().then(setHasCutout);
  }, []);

  return (
    <View style={[
      styles.header,
      hasCutout && styles.headerWithCutout  // Extra padding for cutouts
    ]}>
      <Text>App Header</Text>
    </View>
  );
}

isFoldable()

Platform: Android 9.0+ (API 28) only

Checks if the device is a foldable device (like Samsung Galaxy Fold, Surface Duo, etc.).

static isFoldable(): Promise<boolean>

Returns: Promise<boolean> - True if device is foldable

Example:

import { DeviceGeometry } from 'react-native-device-geometry';

const checkDeviceType = async () => {
  const isFoldable = await DeviceGeometry.isFoldable();
  
  if (isFoldable) {
    console.log('Foldable device detected!');
    // Enable foldable-specific features
    await DeviceGeometry.startHingeMonitoring();
  } else {
    console.log('Standard device');
  }
};

addListener()

Platform: iOS 9.0+ | Android 9.0+ (API 28)

Subscribes to geometry change events. Returns a subscription object that can be used to remove the listener.

static addListener(
  eventName: typeof EVENTS[keyof typeof EVENTS],
  listener: (event: any) => void
): EventSubscription

Parameters:

Prop

Type

Returns: EventSubscription - Subscription object with remove() method

Example - Orientation Changes:

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

// Listen for orientation changes
const subscription = DeviceGeometry.addListener(
  EVENTS.ORIENTATION_CHANGE,
  (event) => {
    console.log('Orientation changed!', event);
    // Update UI layout
  }
);

// Cleanup when done
subscription.remove();

Example - Geometry Updates:

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

const subscription = DeviceGeometry.addListener(
  EVENTS.GEOMETRY_DID_CHANGE,
  async (event) => {
    console.log('Geometry changed:', event);
    
    // Refresh geometry data
    const newGeometry = await DeviceGeometry.getGeometry();
    updateUI(newGeometry);
  }
);

Example - Foldable Hinge Monitoring:

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

// Start monitoring first
await DeviceGeometry.startHingeMonitoring();

// Listen for hinge angle changes
const subscription = DeviceGeometry.addListener(
  EVENTS.HINGE_ANGLE_CHANGE,
  (event) => {
    console.log('Hinge angle:', event.angle);
    
    if (event.angle < 90) {
      console.log('Device is folding!');
    } else if (event.angle > 170) {
      console.log('Device is fully open!');
    }
  }
);

removeAllListeners()

Platform: iOS 9.0+ | Android 9.0+ (API 28)

Removes all event listeners, or all listeners for a specific event.

static removeAllListeners(eventName?: string): void

Parameters:

Prop

Type

Example:

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

// Component cleanup
useEffect(() => {
  const sub1 = DeviceGeometry.addListener(EVENTS.GEOMETRY_DID_CHANGE, handler1);
  const sub2 = DeviceGeometry.addListener(EVENTS.ORIENTATION_CHANGE, handler2);

  return () => {
    // Remove all listeners on unmount
    DeviceGeometry.removeAllListeners();
  };
}, []);

startHingeMonitoring()

Android 10.0+ (API 29)

Starts monitoring hinge angle changes on foldable devices. Must be called before hinge angle events will fire.

static startHingeMonitoring(): Promise<boolean>

Returns: Promise<boolean> - True if monitoring started successfully

Foldable Devices Only - This method only works on foldable devices. Always check isFoldable() first.

Example:

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

async function setupFoldableFeatures() {
  const isFoldable = await DeviceGeometry.isFoldable();
  
  if (isFoldable) {
    const started = await DeviceGeometry.startHingeMonitoring();
    
    if (started) {
      DeviceGeometry.addListener(EVENTS.HINGE_ANGLE_CHANGE, (event) => {
        console.log('Hinge angle:', event.angle);
        adaptUIToFoldAngle(event.angle);
      });
    }
  }
}

stopHingeMonitoring()

Android 10.0+ (API 29)

Stops monitoring hinge angle changes. Call this to cleanup when you no longer need hinge events.

static stopHingeMonitoring(): Promise<boolean>

Returns: Promise<boolean> - True if monitoring stopped successfully

Example:

import { DeviceGeometry } from 'react-native-device-geometry';

// Stop monitoring when component unmounts
useEffect(() => {
  DeviceGeometry.startHingeMonitoring();

  return () => {
    DeviceGeometry.stopHingeMonitoring();
    DeviceGeometry.removeAllListeners(EVENTS.HINGE_ANGLE_CHANGE);
  };
}, []);

React Hooks

useDeviceGeometry()

iOS 9.0+Android 9.0+ (API 28)

React hook that provides device geometry data with automatic updates when geometry changes (orientation, display connection, etc.).

function useDeviceGeometry(options?: GeometryOptions): DeviceGeometryInfo | null

Parameters:

Prop

Type

Returns: DeviceGeometryInfo | null - Current geometry data, or null while loading

Example - Basic Usage:

import { useDeviceGeometry } from 'react-native-device-geometry';

function MyComponent() {
  const geometry = useDeviceGeometry();

  if (!geometry) {
    return <Text>Loading...</Text>;
  }

  return (
    <View>
      <Text>Display: {geometry.mainDisplay.metrics.width}x{geometry.mainDisplay.metrics.height}</Text>
      <Text>Has cutout: {geometry.mainDisplay.cutouts.hasCutout ? 'Yes' : 'No'}</Text>
    </View>
  );
}

Example - With Options:

import { useDeviceGeometry } from 'react-native-device-geometry';

function CutoutRenderer() {
  // Request SVG paths for rendering
  const geometry = useDeviceGeometry({ includePaths: true });

  if (!geometry) return null;

  const cutout = geometry.mainDisplay.cutouts.cutouts[0];

  return (
    <Svg>
      {cutout?.path && (
        <Path d={cutout.path} fill="black" />
      )}
    </Svg>
  );
}

Example - Responding to Changes:

import { useDeviceGeometry } from 'react-native-device-geometry';
import { useEffect } from 'react';

function AdaptiveLayout() {
  const geometry = useDeviceGeometry();

  useEffect(() => {
    if (geometry) {
      const orientation = geometry.mainDisplay.metrics.orientation;
      console.log('Orientation changed to:', orientation);
      // Automatically updates when device rotates!
    }
  }, [geometry]);

  return <View>{/* Your adaptive UI */}</View>;
}

Constants

EVENTS

Available event names for use with addListener(). Import from the package:

import { EVENTS } from 'react-native-device-geometry';

Prop

Type

Example Usage:

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

// Listen to multiple events
DeviceGeometry.addListener(EVENTS.GEOMETRY_DID_CHANGE, handleGeometryChange);
DeviceGeometry.addListener(EVENTS.ORIENTATION_CHANGE, handleOrientationChange);
DeviceGeometry.addListener(EVENTS.DISPLAY_CONNECTED, handleDisplayConnected);

Types

GeometryOptions

Configuration options for getGeometry() and useDeviceGeometry().

Prop

Type

DeviceGeometryInfo

The root object containing all geometry data.

Prop

Type

DisplayGeometryInfo

Detailed geometry information for a single display.

Prop

Type

DisplayMetrics

Physical and logical metrics of a display.

Prop

Type

Cutout

Describes a single physical cutout on the display.

Prop

Type

CutoutInfo

Information about all cutouts on a display.

Prop

Type

CornerProfile

Geometry information for all four screen corners.

Prop

Type

BezierCurve

Raw bezier curve data for advanced rendering.

Prop

Type

CornerGeometry

Geometry data for a single corner.

Prop

Type

Rect

A rectangle defined by origin and dimensions.

Prop

Type

Point

A simple point interface.

Prop

Type


Common Patterns

Dynamic Island Integration

Detect and work with iPhone's Dynamic Island.

import { useDeviceGeometry } from 'react-native-device-geometry';

function DynamicIslandAwareUI() {
  const geometry = useDeviceGeometry();

  if (!geometry) return null;

  const hasDynamicIsland = geometry.mainDisplay.cutouts.cutouts.some(
    cutout => cutout.shapeType === 'pill' // Dynamic Island shape
  );

  return (
    <View style={hasDynamicIsland ? styles.withDynamicIsland : styles.normal}>
      {/* Your UI */}
    </View>
  );
}

Adaptive UI for Cutouts

Automatically adjust UI layout based on cutout locations.

import { DeviceGeometry } from 'react-native-device-geometry';

async function setupAdaptiveUI() {
  const geometry = await DeviceGeometry.getGeometry();
  const cutouts = geometry.mainDisplay.cutouts;

  if (cutouts.hasCutout) {
    // Apply safe insets to avoid cutouts
    const topInset = cutouts.safeInsets.top;
    StatusBar.setbarStyle('light-content');
    
    // Adjust header height
    return { paddingTop: topInset };
  }

  return { paddingTop: 0 };
}

Multi-Display Support

Handle external displays and screen mirroring.

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

function MultiDisplayManager() {
  const [displays, setDisplays] = useState([]);

  useEffect(() => {
    // Get initial displays
    DeviceGeometry.getGeometry().then(geo => {
      setDisplays(geo.displays);
    });

    // Listen for display changes
    const sub1 = DeviceGeometry.addListener(EVENTS.DISPLAY_CONNECTED, () => {
      DeviceGeometry.getGeometry().then(geo => setDisplays(geo.displays));
    });

    const sub2 = DeviceGeometry.addListener(EVENTS.DISPLAY_DISCONNECTED, () => {
      DeviceGeometry.getGeometry().then(geo => setDisplays(geo.displays));
    });

    return () => {
      sub1.remove();
      sub2.remove();
    };
  }, []);

  return (
    <View>
      <Text>Connected displays: {displays.length}</Text>
      {displays.map(display => (
        <Text key={display.displayId}>
          {display.isPrimary ? '📱 ' : '🖥️ '}
          {display.metrics.width}x{display.metrics.height}
        </Text>
      ))}
    </View>
  );
}

Foldable Device Handling

Adapt UI based on foldable device hinge angle.

import { DeviceGeometry, EVENTS } from 'react-native-device-geometry';

function FoldableAdaptiveUI() {
  const [hingeAngle, setHingeAngle] = useState(180);

  useEffect(() => {
    let subscription;

    const setup = async () => {
      const isFoldable = await DeviceGeometry.isFoldable();
      
      if (isFoldable) {
        await DeviceGeometry.startHingeMonitoring();
        
        subscription = DeviceGeometry.addListener(
          EVENTS.HINGE_ANGLE_CHANGE,
          (event) => setHingeAngle(event.angle)
        );
      }
    };

    setup();

    return () => {
      subscription?.remove();
      DeviceGeometry.stopHingeMonitoring();
    };
  }, []);

  // Adapt layout based on hinge angle
  const isFolded = hingeAngle < 90;
  const isTented = hingeAngle > 90 && hingeAngle < 170;
  const isFlat = hingeAngle >= 170;

  return (
    <View>
      {isFolded && <CompactLayout />}
      {isTented && <TentedLayout />}
      {isFlat && <FullLayout />}
    </View>
  );
}