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-bounds

v0.4.2

Published

React Native helpers for screen bounds, safe area, notch, gesture navigation, status bar, and Android system bar insets.

Downloads

260

Readme

react-native-bounds

npm version license React Native

Reliable screen bounds, safe-area helpers, Android navigation-bar detection, status-bar height, and notch/cutout handling for React Native.

react-native-bounds gives you a small API for layouts that need to avoid the real edges of the device: status bars, waterdrop cameras, notches, home indicators, Android three-button navigation, and Android gesture areas.

Highlights

  • Detects Android status bar height.
  • Handles Android waterdrop camera and display cutout top insets.
  • Detects Android three-button navigation bar space.
  • Detects Android gesture navigation space when visible.
  • Reads native Android WindowInsets for production accuracy.
  • Falls back to JavaScript estimates if the native module is unavailable.
  • Estimates iOS notch, Dynamic Island, and home indicator safe areas.
  • Returns usable layout frame after insets.
  • Recomputes on rotation and window-size changes.
  • No extra runtime dependency.

Installation

npm install react-native-bounds

or:

yarn add react-native-bounds

Expo

This package includes Android native code. It works in Expo dev builds and prebuild/native projects.

It will not load the Android native module inside Expo Go.

npx expo run:android

Quick Start

import React from "react";
import { Text, View } from "react-native";
import { useScreenSafeArea } from "react-native-bounds";

export default function App() {
  const bounds = useScreenSafeArea();

  return (
    <View
      style={{
        flex: 1,
        paddingTop: bounds.insets.top,
        paddingBottom: bounds.insets.bottom,
        paddingLeft: bounds.insets.left,
        paddingRight: bounds.insets.right,
      }}
    >
      <Text>Status bar: {bounds.statusBarHeight}</Text>
      <Text>Bottom inset: {bounds.insets.bottom}</Text>
      <Text>Android nav mode: {bounds.androidNavigationMode}</Text>
      <Text>Usable frame height: {bounds.frame.height}</Text>
    </View>
  );
}

Safe Area View

Use ScreenSafeAreaView when you want safe-area padding without writing layout math yourself.

import React from "react";
import { Text } from "react-native";
import { ScreenSafeAreaView } from "react-native-bounds";

export default function Screen() {
  return (
    <ScreenSafeAreaView edges={["top", "bottom"]} style={{ flex: 1 }}>
      <Text>This content avoids the status bar and bottom system area.</Text>
    </ScreenSafeAreaView>
  );
}

Use Without A Component

import { getScreenSafeArea } from "react-native-bounds";

const bounds = getScreenSafeArea();

console.log(bounds.insets);
console.log(bounds.frame);
console.log(bounds.androidNavigationMode);
console.log(bounds.navigationBarHeight);

What You Get

| Field | Description | | --- | --- | | insets | Top, right, bottom, and left safe-area/system-bar inset values. | | frame | Usable content frame after subtracting insets. | | statusBarHeight | Android status bar or iOS top safe-area estimate. | | navigationBarHeight | Android bottom/side navigation-bar size. | | androidNavigationMode | "none", "gesture", "three-button", or "unknown". | | androidNavigationBarPosition | "none", "bottom", "right", "left", or "unknown". | | hasGestureNavigation | True for iOS home indicator or likely Android gesture navigation. | | hasNavigationBar | True when Android navigation-bar space is visible. | | isEstimated | False when Android native insets are used; true for JS estimates. |

Android Navigation Detection

Android can be tricky:

  • Some devices show a classic three-button navigation bar.
  • Some devices use a small gesture area.
  • Some devices report screen and window as the same size even when system bars are visible.
  • Phones with waterdrop cameras may need display cutout safe insets, not just status-bar height.

react-native-bounds handles this by reading native Android WindowInsets when the native module is linked. That lets it detect real status-bar, display-cutout, and navigation-bar insets.

const bounds = getScreenSafeArea();

if (bounds.androidNavigationMode === "three-button") {
  // Keep fixed actions above the Android navigation bar.
}

if (bounds.androidNavigationMode === "gesture") {
  // Avoid placing important controls too close to the gesture area.
}

if (bounds.insets.top > 0) {
  // Content is below the status bar or waterdrop camera cutout.
}

Returned Type

type ScreenSafeArea = {
  insets: {
    top: number;
    right: number;
    bottom: number;
    left: number;
  };
  frame: {
    x: number;
    y: number;
    width: number;
    height: number;
  };
  systemBars: {
    top: number;
    right: number;
    bottom: number;
    left: number;
  };
  orientation: "portrait" | "landscape" | "square";
  statusBarHeight: number;
  navigationBarHeight: number;
  androidNavigationMode: "none" | "gesture" | "three-button" | "unknown";
  androidNavigationBarPosition: "none" | "bottom" | "right" | "left" | "unknown";
  hasNotch: boolean;
  hasHomeIndicator: boolean;
  hasNavigationBar: boolean;
  hasGestureNavigation: boolean;
  isEstimated: boolean;
  isIOS: boolean;
  isAndroid: boolean;
  isPortrait: boolean;
  isLandscape: boolean;
  screenWidth: number;
  screenHeight: number;
  windowWidth: number;
  windowHeight: number;
  screenScale: number;
  fontScale: number;
};

Common Patterns

Floating Bottom Button

const bounds = useScreenSafeArea();

return (
  <Pressable
    style={{
      position: "absolute",
      left: 16,
      right: 16,
      bottom: Math.max(16, bounds.insets.bottom + 12),
    }}
  >
    <Text>Continue</Text>
  </Pressable>
);

Full Screen Content

const bounds = useScreenSafeArea();

return (
  <View
    style={{
      width: bounds.frame.width,
      height: bounds.frame.height,
      marginTop: bounds.insets.top,
      marginLeft: bounds.insets.left,
    }}
  />
);

Debug Device Insets

const bounds = useScreenSafeArea();

console.log({
  insets: bounds.insets,
  statusBarHeight: bounds.statusBarHeight,
  navigationBarHeight: bounds.navigationBarHeight,
  androidNavigationMode: bounds.androidNavigationMode,
  androidNavigationBarPosition: bounds.androidNavigationBarPosition,
  isEstimated: bounds.isEstimated,
});

Accuracy Notes

Android:

  • Uses native WindowInsets when installed in a real Android build.
  • Includes status bar, navigation bar, and display cutout safe top inset.
  • Falls back to StatusBar.currentHeight and dimension-gap estimates if native insets are unavailable.

iOS:

  • Uses JavaScript estimates.
  • Detects common modern iPhone notch and Dynamic Island profiles.
  • Estimates home indicator and landscape side insets.

For exact native safe-area behavior across every platform, OS version, and edge-to-edge mode, react-native-safe-area-context is still a strong choice. Use react-native-bounds when you want a tiny focused helper with Android navigation detection built in.

API

useScreenSafeArea(): ScreenSafeArea
getScreenSafeArea(): ScreenSafeArea
<ScreenSafeAreaView edges={["top", "bottom"]} style={{ flex: 1 }}>
  {children}
</ScreenSafeAreaView>

License

MIT