Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

react-native-orientation-turbo

whitestranger73.3kMIT2.2.0TypeScript support: included

orientation turbo

react-native, orientation, screen-orientation, rotation, portrait, landscape, turbo-module, new-architecture, ios, android

readme

react-native-orientation-turbo 🚀

A React Native library for controlling device orientation with support for locking to portrait, landscape orientations, and real-time orientation change subscriptions. Built with Turbo Modules for optimal performance.

Features

  • Modern Architecture: Built with React Native Turbo Modules
  • Cross Platform: Support for both iOS and Android
  • Orientation Locking: Lock to portrait or landscape orientations
  • Early Orientation Locking: Lock orientation before React Native loads (before bootsplash)
  • AndroidManifest.xml Sync: Automatic synchronization with Android manifest orientation settings
  • State Synchronization: Seamless state sync between Native and JavaScript contexts
  • Event Subscriptions: Subscribe to orientation changes with live updates
  • TypeScript: Full TypeScript support with type definitions
  • Performance: Native performance with Turbo Module architecture

Requirements

  • React Native 0.76+ (Turbo Modules support required)
  • iOS 15.1+
  • Android API level 24+ (Android 7.0)
  • New Architecture enabled (Turbo Modules)

Important: This library requires the New Architecture (Turbo Modules) to be enabled. It does not support the legacy bridge.

Installation

npm install react-native-orientation-turbo

or

yarn add react-native-orientation-turbo

iOS Setup

  1. Install pods:

    cd ios && pod install
  2. Modify your AppDelegate.swift file:

Add the import statement:

import OrientationTurbo

Add the orientation support method:

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
  return OrientationTurbo.shared.getSupportedInterfaceOrientations()
}

Your AppDelegate.swift should look like this:

import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
import OrientationTurbo  // Add this import

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  // ... other code ...

  // Add this method
  func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return OrientationTurbo.shared.getSupportedInterfaceOrientations()
  }
}

Android Setup

No additional setup required for Android.

Note: The library automatically syncs with your AndroidManifest.xml orientation settings. If you have android:screenOrientation set in your manifest, the library will respect and sync with those settings into state on initialization.

Migration Guide

If you're upgrading from a previous version, please check our Migration Guide for any breaking changes and upgrade instructions.

v2.2.0 Breaking Changes: iOS native API changed from OrientationTurboImpl.shared to OrientationTurbo.shared. React Native usage remains unchanged.

Usage

import {
  lockToPortrait,
  lockToLandscape,
  unlockAllOrientations,
  getCurrentOrientation,
  isLocked,
  getDeviceAutoRotateStatus,
  onOrientationChange,
  onLockOrientationChange,
  startOrientationTracking,
  stopOrientationTracking,
  PortraitDirection,
  Orientation,
  LandscapeDirection,
  type OrientationSubscription,
  type LockOrientationSubscription,
  type DeviceAutoRotateStatus,
} from 'react-native-orientation-turbo';

Basic Examples

// Starts tracking native sensors for onOrientationChange.
startOrientationTracking();

// Stops tracking native sensors.
stopOrientationTracking();

// Lock to portrait orientation
lockToPortrait();

// Lock to portrait UPSIDE_DOWN orientation
lockToPortrait(PortraitDirection.UPSIDE_DOWN);

// Lock to landscape left
lockToLandscape(LandscapeDirection.LEFT);

// Lock to landscape right  
lockToLandscape(LandscapeDirection.RIGHT);

// Unlock all orientations (allow rotation)
unlockAllOrientations();

// Get current orientation. If screen is locked - returns lock state, if not - returns current device orientation
const currentOrientation = getCurrentOrientation();
console.log(currentOrientation); // 'PORTRAIT' | 'LANDSCAPE_LEFT' | 'LANDSCAPE_RIGHT' | 'FACE_UP' | 'FACE_DOWN'

// Check if orientation is currently locked
const locked = isLocked();
console.log(locked); // true | false

// Get device auto-rotate status (Android only). iOS will return null
const autoRotateStatus = getDeviceAutoRotateStatus();
console.log(autoRotateStatus); // { isAutoRotateEnabled: boolean, canDetectOrientation: boolean } | null

// Subscribe to lock orientation changes
onLockOrientationChange(({ orientation, isLocked }) => {
  // Your code there
})

// Subscribe to device orientation changes
onOrientationChange(({ orientation }) => {
  // Your code there
})

API Reference

Methods

startOrientationTracking(): void

Starts using native sensors to track device orientation changes. When device is physically rotates - sensors are detecting changes and expose it via onOrientationChange subscription. Drains battery faster and uses device power resources. Recommended to use only when sensors are needed and remove when not needed remove sensors tracking by using stopOrientationTracking.

startOrientationTracking();

stopOrientationTracking(): void

Stops using native sensors if it's used. Physical devices rotation would no longer be tracked.

stopOrientationTracking();

lockToPortrait(direction?: PortraitDirection): void

Locks the device orientation to portrait mode.

Parameters:

  • direction?: PortraitDirection.UP or PortraitDirection.UPSIDE_DOWN or undefined
import { PortraitDirection } from 'react-native-orientation-turbo';

lockToPortrait(); // same as lockToPortrait(PortraitDirection.UP)
lockToPortrait(PortraitDirection.UP);
lockToPortrait(PortraitDirection.UPSIDE_DOWN);

lockToLandscape(direction: LandscapeDirection): void

Locks the device orientation to landscape mode in the specified direction.

Parameters:

  • direction: LandscapeDirection.LEFT or LandscapeDirection.RIGHT
import { LandscapeDirection } from 'react-native-orientation-turbo';

lockToLandscape(LandscapeDirection.LEFT);
lockToLandscape(LandscapeDirection.RIGHT);

unlockAllOrientations(): void

Unlocks the orientation, allowing the device to rotate freely based on device rotation.

unlockAllOrientations();

getCurrentOrientation(): string

Returns the current device orientation.

Returns: 'PORTRAIT' | 'LANDSCAPE_LEFT' | 'LANDSCAPE_RIGHT' | 'FACE_UP' | 'FACE_DOWN'

const orientation = getCurrentOrientation();

isLocked(): boolean

Returns whether the orientation is currently locked.

Returns: true if orientation is locked, false if unlocked

const locked = isLocked();

getDeviceAutoRotateStatus(): DeviceAutoRotateStatus | null

Android only. Returns information about the device's auto-rotate settings and orientation detection capabilities.

Returns:

  • DeviceAutoRotateStatus object on Android
  • null on iOS (not supported)

iOS Limitation: This method is not available on iOS due to platform restrictions. See iOS Auto-Rotate Detection Limitations for detailed explanation and alternative approaches.

DeviceAutoRotateStatus Properties:

  • isAutoRotateEnabled: boolean - Whether auto-rotate is enabled in device settings
  • canDetectOrientation: boolean - Whether the device can detect orientation changes
import { getDeviceAutoRotateStatus } from 'react-native-orientation-turbo';

const status = getDeviceAutoRotateStatus();
if (status) {
  console.log('Auto-rotate enabled:', status.isAutoRotateEnabled);
  console.log('Can detect orientation:', status.canDetectOrientation);
} else {
  console.log('Auto-rotate status not supported on this platform');
}

Subscriptions

onLockOrientationChange(callback: (subscription: LockOrientationSubscription) => void)

Subscribes to orientation changes and receives real-time updates.

Parameters:

  • callback: Function called when lock state orientation changes, receives LockOrientationSubscription object

Returns: Subscription object with remove() method to unsubscribe

import { onLockOrientationChange } from 'react-native-orientation-turbo';

const subscription = onLockOrientationChange(({ orientation, isLocked }) => {
  console.log('Current orientation:', orientation);
  console.log('Is locked:', isLocked);
});

// Unsubscribe when no longer needed
subscription.remove();

React Hook Example:

import { useEffect, useRef } from 'react';
import type { EventSubscription } from 'react-native';

import { onLockOrientationChange } from 'react-native-orientation-turbo';

const MyComponent = () => {
  const lockListenerSubscription = useRef<null | EventSubscription>(null);

  useEffect(() => {
    lockListenerSubscription.current = onLockOrientationChange(({ orientation, isLocked }) => {
      // Handle orientation change
      console.log('Orientation:', orientation, 'Locked:', isLocked);
    });

    return () => {
      lockListenerSubscription.current?.remove();
      lockListenerSubscription.current = null;
    }; // Clean up subscription
  }, []);

  return <View>{/* Your component */}</View>;
};

onOrientationChange(callback: (subscription: OrientationSubscription) => void)

Subscribes to orientation changes and receives real-time updates.

Parameters:

  • callback: Function called when device physical orientation changes, receives OrientationSubscription object

Returns: Subscription object with remove() method to unsubscribe

import { onOrientationChange } from 'react-native-orientation-turbo';

const subscription = onOrientationChange(({ orientation }) => {
  console.log('Current device orientation:', orientation);
});

// Unsubscribe when no longer needed
subscription.remove();

React Hook Example:

import { useEffect, useRef } from 'react';
import type { EventSubscription } from 'react-native';

import { onOrientationChange } from 'react-native-orientation-turbo';

const MyComponent = () => {
  const listenerSubscription = useRef<null | EventSubscription>(null);

  useEffect(() => {
    listenerSubscription.current = onOrientationChange(({ orientation }) => {
      // Handle orientation change
      console.log('Orientation:', orientation);
    });

    return () => {
      listenerSubscription.current?.remove();
      listenerSubscription.current = null;
    }; // Clean up subscription
  }, []);

  return <View>{/* Your component */}</View>;
};

Types

LandscapeDirection

enum LandscapeDirection {
  LEFT = 'LEFT',
  RIGHT = 'RIGHT',
}

PortraitDirection

enum PortraitDirection {
  UP = 'UP',
  UPSIDE_DOWN = 'UPSIDE_DOWN', // iOS only
}

Orientation

enum Orientation {
  PORTRAIT = 'PORTRAIT',
  LANDSCAPE_LEFT = 'LANDSCAPE_LEFT',
  LANDSCAPE_RIGHT = 'LANDSCAPE_RIGHT',
  FACE_UP = 'FACE_UP', // iOS only
  FACE_DOWN = 'FACE_DOWN', // iOS only
}

LockOrientationSubscription

type LockOrientationSubscription = {
  orientation: Orientation | null;
  isLocked: boolean;
};

OrientationSubscription

type OrientationSubscription = {
  orientation: Orientation;
};

DeviceAutoRotateStatus

type DeviceAutoRotateStatus = {
  isAutoRotateEnabled: boolean;
  canDetectOrientation: boolean;
};

Advanced Features

Early Orientation Locking

Lock orientation before React Native loads (useful for preventing orientation changes during app initialization/bootsplash):

iOS - AppDelegate.swift:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Lock orientation BEFORE React Native loads
    OrientationTurbo.shared.lockToPortrait()

    // Your existing setup...
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

Android - MainActivity.kt:

override fun onCreate(savedInstanceState: Bundle?) {
    // Lock orientation BEFORE React Native loads
    OrientationTurbo.lockToPortrait(this)

    super.onCreate(savedInstanceState)
}

AndroidManifest.xml Synchronization

The library automatically syncs with your Android manifest orientation settings:

<activity android:screenOrientation="portrait">
  <!-- Library will automatically sync to portrait on initialization -->
</activity>

State Synchronization

Early orientation locks are automatically synchronized with your JavaScript context when the library initializes, ensuring consistent state across native and JavaScript.

For comprehensive documentation on advanced features, early orientation locking, state synchronization, and integration patterns, see Advanced Usage Guide.

For detailed information on using the library natively in iOS and Android applications, including architecture, restrictions, and best practices, see Native Usage Guide.

Complete Example

Please visit example folder on github page.

Enabling New Architecture

This library requires React Native's New Architecture (Turbo Modules). Please refer to React Native docs on how to enable it.

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT


Made with create-react-native-library

changelog

Changelog

All notable changes to this project will be documented in this file.

[2.2.0] - 2025-07-28

Added

Android

  • Shared State Architecture: New OrientationState.kt package-private singleton for unified state management across native and React Native contexts
  • Static Status Methods: Added status checking methods available in static context:
    • getCurrentOrientation() - Get current orientation as String
    • isLocked() - Check if orientation is currently locked
    • getLockedOrientation() - Get the locked orientation as Orientation enum
    • getDeviceOrientation() - Get physical device orientation as Orientation enum
  • Perfect State Synchronization: Immediate consistency between native and React Native contexts without manual synchronization
  • Thread-Safe Operations: All orientation state operations are now thread-safe and can be called from any context

Fixed

Android

  • Wrong Landscape Direction For Manifest Sync: After 2.1.2 fix, manifest was still returning wrong landscape type. It's fixed now
  • State Persistence: Orientation state now properly persists across Activity lifecycle events and React Native reloads
  • Memory Leaks: Eliminated potential memory leaks in state management by using singleton pattern

Breaking Changes

iOS

  • Public Protocol Changes: OrientationTurboImpl.shared changed to OrientationTurbo.shared for native integration

    // Before
    OrientationTurboImpl.shared.lockToPortrait()
    
    // After  
    OrientationTurbo.shared.lockToPortrait()

Technical Improvements

iOS

  • Codebase Refactoring: Complete iOS architecture redesign with improved separation of concerns
  • Protocol-Based API: New OrientationTurboPublicProtocol for clean native integration interface
  • Memory Management: Enhanced memory management and lifecycle handling

Android

  • Shared State Pattern: Replaced multiple state holders with single OrientationState.kt source of truth
  • Simplified Architecture: Eliminated complex synchronization logic by using unified state management
  • Package-Private State: OrientationState is internal to com.orientationturbo package ensuring proper encapsulation
  • Eliminated State Duplication: Removed redundant state properties from OrientationManager and other components
  • Simplified OrientationSync: Removed unnecessary state clearing and intermediate data classes

Documentation

Major Updates

  • Native Usage Guide: Comprehensive docs/NATIVE_USAGE.md rewrite with new Android shared state architecture
  • Updated Code Examples: All Android examples updated to show Activity context requirements and new status methods
  • Architecture Diagrams: New architectural flow diagrams showing shared state pattern
  • Migration Instructions: Clear migration path for breaking changes with before/after code examples

Content Improvements

  • Integration Patterns: Advanced integration patterns showing real-time orientation monitoring
  • Thread Safety: Documentation of thread-safe operations and context requirements

API Documentation

  • Method Signatures: Updated all Android method signatures with Activity context requirements
  • Status Methods: Complete documentation of new Android status checking capabilities
  • Import Statements: Updated import examples with required enum imports

Example Application

  • Version Bump: All dependencies updated to latest versions
  • Demo Updates: Example app updated to demonstrate new status methods and shared state features

[2.1.2] - 2025-07-18

Fixed

Android

  • Landscape reverse issue: LANDSCAPE_RIGHT & LANDSCAPE_LEFT now no longer locks in reverse

Added

Android

  • Device Auto-Rotate Status: getDeviceAutoRotateStatus() method to check device auto-rotate settings and orientation detection capabilities
  • DeviceAutoRotateStatus Type: New TypeScript type for auto-rotate status information

Documentation

  • iOS Auto-Rotate Limitations Guide: New docs/IOS_AUTO_ROTATE_LIMITATIONS.md explaining iOS platform restrictions for auto-rotate detection and providing alternative approaches
  • API documentation improved: Typescript annotations were added to API functions

Technical

  • Android codebase improvements: Codebase for Android was redesigned and improved

[2.1.1] - 2025-07-11

Added

iOS

  • FACE_UP & FACE_DOWN orientation support: FACE_UP and FACE_DOWN support. Enum Orientation type was updated

[2.1.0] - 2025-07-10

Added

Early Orientation Locking

  • Pre-React Native Orientation Control: Lock orientation before React Native loads (before bootsplash screen)
  • iOS Early Locking: OrientationTurboImpl.shared.lockToPortrait() and OrientationTurboImpl.shared.lockToLandscape() methods for AppDelegate integration
  • Android Early Locking: OrientationTurbo.lockToPortrait() and OrientationTurbo.lockToLandscape() static methods for MainActivity integration
  • State Synchronization: Automatic sync between early native orientation locks and JavaScript context on library initialization

Android

  • Native Static Class: OrientationTurbo singleton class with static methods for early orientation control
  • OrientationSync Utility: OrientationSync.kt utility class for state management and synchronization
  • AndroidManifest.xml Sync: Automatic synchronization with android:screenOrientation manifest settings on initialization
  • State Persistence: Shared state management between early native locks and OrientationTurboModule

Fixes

iOS

  • unlockAllOrientations functionality fix: Redundant dispatch was removed and execution order corrected
  • getLockCurrentOrientation fix: Function now properly returns locked orientation state vs device orientation
  • null state for onLockOrientationChange: onLockOrientationChange orientation now returns null for iOS when orientation is not locked

Docs

  • Advanced Usage Guide: Comprehensive docs/ADVANCED_USAGE.md with early locking examples, state synchronization, and integration patterns
  • README.md Enhanced: Added advanced features section with early locking examples and AndroidManifest.xml sync information
  • Documentation Structure: Organized documentation with clear separation between basic and advanced usage

[2.0.0] - 2025-07-07

Added

  • Physical Device Orientation Tracking: startOrientationTracking() and stopOrientationTracking() - Control native sensor tracking for device orientation changes
  • Enhanced Orientation Subscription: Physical device orientation changes now detected via native sensors when tracking is enabled
  • IOS UPSIDE_DOWN orientation support: Portrait enum now have UPSIDE_DOWN that's can be detected only by iOS devices
  • Battery Optimization: Orientation tracking can be started/stopped as needed to conserve battery and device resources

Fixed

  • iOS Lock Functionality: Resolved orientation locking issues on iOS platform for improved reliability

Changed

  • Orientation Lock Subscription: now runs with onLockOrientationChange. onOrientationChange now tracking device orientation
  • Orientation Change Detection: onOrientationChange now added and requires startOrientationTracking() to be called first for physical device rotation detection
  • Performance Improvements: More efficient orientation change handling with optional sensor tracking

Documentation

  • README.md updated with iOS setup instructions including AppDelegate.swift configuration
  • Added startOrientationTracking() and stopOrientationTracking() API documentation
  • Added onLockOrientationChange API documentation
  • Changed onOrientationChange API documentation
  • Types and Enums documentation is enhanced
  • Enhanced setup guide with detailed iOS integration steps

[1.0.0] - 2025-07-06

Added

  • Orientation Change Subscription: onOrientationChange(callback: { callback: (subscription: LockOrientationSubscription) => void }) - Subscribe to real-time orientation changes

Documentation

  • README.md updated with new onOrientationChange(callback)
  • /example is updated to demonstrate onOrientationChange(callback) usage

[0.1.0] - 2025-07-05

Initial Release

Features

Core Orientation Control
  • Lock to Portrait: lockToPortrait() - Lock device to portrait orientation
  • Lock to Landscape: lockToLandscape(direction) - Lock to landscape left or right
  • Unlock All Orientations: unlockAllOrientations() - Allow free rotation
  • Get Current Orientation: getCurrentOrientation() - Retrieve current device orientation
  • Check Lock Status: isLocked() - Determine if orientation is currently locked
TypeScript Support
  • Full TypeScript definitions with complete type safety
  • Enum exports: LandscapeDirection and Orientation enums
  • Type-safe API with proper return types and parameter validation
Platform Support
  • iOS 11.0+ - Native implementation using iOS orientation APIs
  • Android API 21+ - Native implementation using Android orientation APIs
  • Turbo Module Architecture - Built with React Native's New Architecture

Technical Specifications

Architecture Requirements
  • React Native 0.70+ required
  • New Architecture (Turbo Modules) - No legacy bridge support
Package Contents
  • Native iOS implementation (Objective-C/Swift)
  • Native Android implementation (Kotlin)
  • TypeScript definitions
  • Complete documentation with examples

Installation & Setup

npm install react-native-orientation-turbo
# or
yarn add react-native-orientation-turbo

New Architecture Setup Required:

  • iOS: Enable New Architecture in Podfile
  • Android: Set newArchEnabled=true in gradle.properties

API Overview

import {
  lockToPortrait,
  lockToLandscape,
  unlockAllOrientations,
  getCurrentOrientation,
  isLocked,
  LandscapeDirection,
  Orientation,
} from 'react-native-orientation-turbo';

// Lock orientations
lockToPortrait();
lockToLandscape(LandscapeDirection.LEFT);
lockToLandscape(LandscapeDirection.RIGHT);

// Unlock
unlockAllOrientations();

// Check status
const orientation = getCurrentOrientation(); // 'PORTRAIT' | 'LANDSCAPE_LEFT' | 'LANDSCAPE_RIGHT'
const locked = isLocked(); // boolean

Documentation

  • Complete README with setup instructions
  • API reference with all methods documented
  • Real-world usage examples
  • New Architecture enablement guide
  • Platform-specific setup instructions

Important Notes

  • New Architecture Only: This library requires Turbo Modules enabled
  • No Legacy Bridge Support: Not compatible with old React Native architecture