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-status-edge

v0.3.3

Published

[Development preview] A high-performance, Skia-powered fluid status indicator and dynamic notch animation library for React Native.

Readme

react-native-status-edge

🚧 Development preview — not a production release. This is a work-in-progress (v0.3.3). APIs, behavior, and native geometry may change without notice, and some platforms/devices are still being calibrated. Use at your own risk. See License — this is proprietary, source-available software, not open source.

A high-performance, Skia-powered fluid status indicator and dynamic notch animation library for React Native.

It detects your device's screen cutout (Notch, WaterDrop, Dot/punch-hole, Dynamic Island, or None) and renders a glowing comet that follows the cutout boundary — perfect as a "loading" indicator that wraps the camera.

Requirements

  • React Native >= 0.71 (New Architecture / TurboModules)
  • Android API 31+ (Android 12+) for runtime cutout detection
  • iOS 13+ / iPhone 11+ for notch/island detection
  • Edge-to-edge rendering must be enabled so the overlay can draw over the status bar / cutout (the setup wizard configures this for you — see below)

Installation

npm install react-native-status-edge

Peer dependencies

The library renders with Skia and animates with Reanimated. Install:

npm install @shopify/react-native-skia react-native-reanimated

If you use Reanimated 4, also install its worklets runtime:

npm install react-native-worklets

Reanimated requires its Babel plugin (react-native-worklets/plugin for v4, or react-native-reanimated/plugin for v3) to be the last entry in your babel.config.js.

Setup (runs automatically)

When you install the package, a setup step runs automatically (via postinstall): it checks your peer dependencies and enables Android edge-to-edge (the transparent top area the overlay needs). You don't need to run any command.

To re-run it manually (e.g. after adding native folders or on Expo prebuild):

npx react-native-status-edge setup    # interactive setup
npx react-native-status-edge doctor   # just check peer dependencies

iOS

cd ios && pod install

Why edge-to-edge?

StatusEdge draws the glow over the status-bar / cutout area. If your app is not edge-to-edge (i.e. the top of the screen is opaque), the overlay is clipped and the animation breaks — most visibly on WaterDrop and other top-attached cutouts. The wizard sets edgeToEdgeEnabled=true in android/gradle.properties (React Native 0.81+). iOS already extends views under the notch/island, so no change is needed there.

Usage

Basic — show a loading animation

import { StatusEdge } from 'react-native-status-edge';

export default function App() {
  return (
    <>
      {/* Your app content */}
      <StatusEdge isLoading color="#00FF00" strokeWidth={3} />
    </>
  );
}

Control the loading state

import { useState } from 'react';
import { Button, View } from 'react-native';
import { StatusEdge } from 'react-native-status-edge';

export default function App() {
  const [isLoading, setIsLoading] = useState(false);

  const handleFetch = async () => {
    setIsLoading(true);
    await fetchData();
    setIsLoading(false);
  };

  return (
    <View style={{ flex: 1 }}>
      <Button title="Fetch" onPress={handleFetch} />
      <StatusEdge isLoading={isLoading} color="#6366F1" strokeWidth={4} />
    </View>
  );
}

useStatusEdge — access raw cutout data

import { useStatusEdge } from 'react-native-status-edge';

export default function DebugScreen() {
  const data = useStatusEdge();
  if (!data) return null;

  console.log(data.cutoutType);  // 'Notch' | 'WaterDrop' | 'Dot' | 'Island' | 'None'
  console.log(data.cutoutRects); // [{ x, y, width, height }] in dp
  console.log(data.cameraCircles); // [{ cx, cy, r }] in dp (Android, Dot)
  return null;
}

API

<StatusEdge /> props

| Prop | Type | Default | Description | |------|------|---------|-------------| | isLoading | boolean | false | Show/hide the animation | | color | string | '#00FF00' | Color of the glow/comet (any CSS color) | | strokeWidth | number | 3 | Comet/glow stroke thickness in dp | | animation | AnimationStyle | 'trace' | Animation style (see below) | | durationMs | number | 2000 / 2600 | One full cycle in ms (travel / breathing-pulse) |

Animation styles

Every style works on every cutout type (Notch, WaterDrop, Dot, Island, None).

| animation | Behaviour | |-------------|-----------| | trace | The original per-cutout comet: a beam enters top-left, traces the cutout, exits top-right. Default — existing usage is unchanged. | | clockwise | The beam travels the top edge + cutout continuously, clockwise (Dot/Island orbit the shape). | | counterclockwise | Same path, reversed direction. | | breathing | No travel — the full screen border + cutout outline glow smoothly fade in and out. | | pulse | No travel — the full screen border + cutout outline emit a quick double "heartbeat" flash, then rest. |

useStatusEdge()

Returns StatusEdgeData | null. It is null while the native module is loading and if detection fails (see Known limitations).

interface StatusEdgeData {
  cutoutType: 'Notch' | 'WaterDrop' | 'Dot' | 'Island' | 'None';
  /** Bounding rectangles of all cutouts, in dp. */
  cutoutRects: Array<{ x: number; y: number; width: number; height: number }>;
  /** Exact camera circle(s), in dp. Android only; populated for Dot/Island. */
  cameraCircles: Array<{ cx: number; cy: number; r: number }>;
  /** Top safe-area inset, in dp. */
  safeAreaTop: number;
  /** Index into `cutoutRects` of the primary cutout (Notch/WaterDrop render around it). */
  mainRectIndex?: number;
  /** SVG-like polyline of the cutout path, in physical px. Android only. */
  cutoutPathSvg?: string;
  /** Bounding box of the cutout path, in dp. Android only. */
  cutoutPathBounds?: { x: number; y: number; width: number; height: number } | null;
}

Exported types: StatusEdgeData, CutoutType, CutoutRect, CameraCircle, StatusEdgeProps, AnimationStyle. src/types.ts is the source of truth.

Cutout types

| Type | Description | |------|-------------| | Notch | Wide notch attached to the top edge | | WaterDrop | Narrow teardrop notch attached to the top edge | | Dot | Small punch-hole camera | | Island | Dynamic Island / wide floating pill | | None | No cutout detected |

How it works

  1. Native detection — On Android, DisplayCutout (API 31+) provides the bounding rects, safe inset, and cutout path. For a center punch-hole on Samsung One UI the OS reports a tall safe-area stripe (not the bare circle), so the camera circle is taken from the center of that box. On iOS the device model identifier is mapped to a cutout type with approximate dimensions. On iOS, every model from the iPhone 11 onward (through the iPhone 17 family, 16e and Air) is mapped to its cutout type and dimensions, with a safe-area fallback for future devices.
  2. Path construction — A Skia path traces the cutout boundary; an EvenOdd clip keeps the glow outside the cutout interior.
  3. Animation — Travelling styles (trace/clockwise/counterclockwise) drive a start/end offset along the path; breathing/pulse animate the opacity of the full screen-border + cutout outline. All are layered with three BlurMask passes.

Known limitations

This is a development preview. Current known gaps:

  • Orientation: cutout geometry is read once on mount; rotating the device may misalign the overlay until remount. Designed for portrait.
  • iOS dimensions are hardcoded approximations per device family; the simulator always reports None. cameraCircles is Android-only.
  • Samsung Dot vertical centering is calibrated to the geometric center of the reported cutout stripe; a few-dp per-device offset may remain.
  • Detection failures currently surface as null (no error channel yet).

License

Proprietary — © 2026 Armağan Tambova. All rights reserved.

You may use this library, unmodified, as a dependency inside your own application (including commercial apps). You may not redistribute it, create derivative works or new versions, use it in tutorials/educational material, or monetize the library itself. All development and distribution rights are reserved by the author. See LICENSE for the full terms.

This is not open source and external contributions, forks, and derivatives are not accepted. For any use beyond the granted permissions, contact [email protected].