npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-hinge

v0.3.0

Published

Continuous hinge angle reading and folding posture monitoring for iOS and Android with Nitro Modules and UI-thread Worklets

Readme

react-native-hinge

A cross-platform React Native native library built with Nitro Modules exposing continuous hinge angle reading and folding posture monitoring for iOS (UIKit UIHingeInteraction) and Android (Jetpack WindowManager & TYPE_HINGE_ANGLE sensor) to JavaScript with zero-latency UI-thread Worklet support (react-native-worklets).

Architecture inspired by Apple Tech Talk 111464: "Take advantage of the unique features of iPhone Duo" (Chris Donegan, Engineering Manager in UI Frameworks & Alex Muller, System Experience Engineer) and Android Jetpack WindowManager foldable standards.

[!IMPORTANT] Requirements:

  • iOS: Native hinge interaction requires Xcode 27.1+ (iOS 27.1 SDK) on hardware supporting UIHingeInteraction (e.g. iPhone Duo).
  • Android: Requires Android API 24+ (minSdkVersion 24). Continuous angle readings use Android's TYPE_HINGE_ANGLE hardware sensor (API 30+), and posture tracking is powered by Jetpack WindowManager across foldable form-factors (Samsung Galaxy Z Fold/Flip, Google Pixel Fold, OnePlus Open, Motorola Razr, Microsoft Surface Duo, etc.).
  • Graceful Fallback: Non-foldable devices, older OS versions, and Web safely fallback to a lightweight no-op without throwing errors or breaking builds.

🌟 Features

  • Nitro Modules Architecture: Ultra-fast C++, Swift, and Kotlin Hybrid Objects with direct JSI bindings and zero serialization overhead.
  • 🧵 Zero-Latency UI-Thread Worklets: Directly observe continuous hinge angle streams using react-native-worklets running synchronously on the UI Runtime.
  • 📐 Unified Status & Angles:
    • High-level hinge status: 'closed' | 'partiallyOpen' | 'fullyOpen' | 'unknown'.
    • Continuous hinge angle updates (ideal for live effects and interactions like pitch bends, 3D folding transforms, or responsive layouts).
    • Hardware detection via isSupported.
  • 🍏 Native iOS 27.1 Support: Full native implementation using UIKit's UIHingeInteraction.
  • 🤖 Native Android Support: Full native implementation combining Android Jetpack WindowManager (FoldingFeature) and Android Sensor.TYPE_HINGE_ANGLE.
  • 🛡️ Cross-Platform Safe: Standard non-foldable phones, Web, and legacy OS versions safely fallback without crashing.
  • 📱 Included Interactive Example App: Telemetry, live posture monitor, and whammy-bar pitch bend demo.

📦 Installation

npm install react-native-hinge react-native-nitro-modules react-native-worklets
# or
bun add react-native-hinge react-native-nitro-modules react-native-worklets
# or
yarn add react-native-hinge react-native-nitro-modules react-native-worklets

iOS Setup

Install CocoaPods:

cd ios && pod install

Android Setup

Android autolinking is configured out-of-the-box via React Native and Nitro Modules. No additional manual steps are required.


🛠️ Nitro Codegen

To regenerate C++, Swift, and Kotlin bindings whenever specs change:

npm run codegen

🚀 Usage

1. Live Interactive Effects with UI-Thread Worklets

Native APIs report the angle in radians (0 to π). useHingeAngle defaults to radians (unit: 'radians'), matching native platforms. You can pass unit: 'degrees' (0° to 180°) whenever preferred:

import React, { useCallback } from 'react'
import { useHingeAngle, type HingeUpdate } from 'react-native-hinge'

export function FoldableInteractionView() {
  // Memoize callback to prevent re-declaring on every render
  const onHingeUpdate = useCallback((update: HingeUpdate) => {
    'worklet'
    if (update.status === 'partiallyOpen') {
      // update.angle: continuous hinge opening angle (radians by default, or degrees if unit: 'degrees')
      // Drive live interaction (e.g. whammy-bar pitch bend, 3D folding transform)
    } else {
      // Reset effect when device is not in partially open state
    }
  }, [])

  const { angle, status, isSupported } = useHingeAngle({
    unit: 'degrees', // 'degrees' (0° to 180°) or 'radians' (default, 0 to π)
    onHingeUpdate,
  })

  return null
}

2. Direct Subscription API (subscribeToHinge)

You can subscribe directly to continuous hinge updates outside of React components or inside custom stores. The low-level subscribeToHinge passes native values in radians. Conversion helpers radiansToDegrees and degreesToRadians are exported for convenience:

import { subscribeToHinge, radiansToDegrees } from 'react-native-hinge'

const unsubscribe = subscribeToHinge((update) => {
  const degrees = radiansToDegrees(update.angle)
  console.log('Live angle (rad):', update.angle, 'degrees:', degrees, 'Status:', update.status)
})

// Stop observing and release resources:
unsubscribe()

3. High-Level Hinge Status Hook (useHingeStatus)

Track discrete posture transitions (closed -> partiallyOpen -> fullyOpen -> unknown):

import React from 'react'
import { useHingeStatus } from 'react-native-hinge'

export function AdaptiveLayout() {
  const status = useHingeStatus()

  if (status === 'partiallyOpen') {
    return <DualPaneOrBookLayout />
  }

  return <StandardCanvasLayout />
}

📐 Hinge Status Reference

| Status | iOS (UIHinge) | Android (WindowManager & Sensor) | Description | | :--- | :--- | :--- | :--- | | closed | UIHinge.Status.closed | - | Device is folded shut, outer display active. | | partiallyOpen | UIHinge.Status.partiallyOpen | FoldingFeature.State.HALF_OPENED | Device is between closed and flat (Tabletop, Book, Tent). Angle is actively read to drive interactions. | | fullyOpen | UIHinge.Status.fullyOpen | FoldingFeature.State.FLAT | Continuous large canvas unfolded flat (180°). | | unknown | - | No folding feature or sensor-only | Standalone sensor reading without an associated folding feature, or flat non-separating display. |


📄 License

MIT