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-stay-awake

v1.0.0

Published

Keep the screen awake / prevent the screen from sleeping in React Native. New Architecture TurboModule with useKeepAwake hook, tag-based reference counting, and web Wake Lock support. Replacement for the deprecated react-native-keep-awake.

Downloads

149

Readme

react-native-stay-awake

npm version npm downloads CI types license

Keep the screen awake / keep the screen on in React Native — prevent the screen from sleeping, dimming, or timing out while your app shows video, navigation, downloads, recipes, or a workout. Built for the New Architecture (TurboModule) with a hooks-first API, tag-based reference counting, and web support via the Screen Wake Lock API. Works on iOS, Android, Web, tvOS, and visionOS — with no Expo dependency.

A modern replacement for the deprecated react-native-keep-awake, and an expo-keep-awake alternative for bare React Native apps that don't want expo-modules-core.

Why this library?

| | react-native-stay-awake | react-native-keep-awake (deprecated) | expo-keep-awake | @sayem314/react-native-keep-awake | | --- | :---: | :---: | :---: | :---: | | New Architecture (TurboModule) | ✅ | ❌ | ✅ | ✅ | | Works without Expo modules | ✅ | ✅ | ❌ (needs expo-modules-core) | ✅ | | Reference counting (tags) | ✅ | ❌ | ✅ | ❌ (components cancel each other) | | useKeepAwake() hook | ✅ | ❌ | ✅ | ✅ | | Unique auto-tag per hook instance | ✅ | — | ✅ | ❌ | | Web (Screen Wake Lock API) | ✅ | ❌ | ✅ | ❌ (empty stub) | | Auto re-acquire wake lock on tab focus (web) | ✅ | — | ❌ | — | | Query active state / tags from JS | ✅ | ❌ | ❌ (native-only, unexported) | ❌ | | Survives Android activity recreation | ✅ | ❌ | ❌ (tag set survives, flag doesn't) | ❌ | | Safe when Android activity is null | ✅ | ❌ (crashes) | ✅ (since 55.0.7) | ✅ | | Idempotent deactivate everywhere | ✅ | ❌ | ❌ (web throws on unknown tag) | ✅ | | Cleans up on JS reload | ✅ | ❌ (state leaks) | ✅ | ❌ | | Shipped Jest mock | ✅ | ❌ | ❌ | ❌ | | TypeScript | ✅ | ❌ (types never published) | ✅ | ✅ | | tvOS / visionOS podspec support | ✅ / ✅ | ❌ (removed) | ✅ / ❌ | ❌ |

Installation

npm install react-native-stay-awake
# or
yarn add react-native-stay-awake

Then rebuild your app (cd ios && pod install for bare iOS projects). Autolinking does the rest — no manual linking, no MainApplication edits.

Requires React Native 0.76+ (New Architecture). No Expo dependency, but works fine inside Expo dev clients too.

Usage

Hook (recommended)

import { useKeepAwake } from 'react-native-stay-awake';

function VideoPlayer() {
  useKeepAwake(); // screen stays awake while this component is mounted
  return <Video />;
}

Each hook instance gets its own reference-counted tag, so multiple components can keep the screen awake independently — the screen is allowed to sleep only after the last one unmounts. No more "component A unmounted and turned off the wake lock that component B still needed".

Toggle without unmounting:

useKeepAwake('player', { enabled: isPlaying });

Imperative API

import {
  activateKeepAwake,
  deactivateKeepAwake,
  deactivateAllKeepAwake,
  isKeepAwakeActive,
  getActiveKeepAwakeTags,
  isKeepAwakeAvailable,
} from 'react-native-stay-awake';

activateKeepAwake('download');       // hold with a tag
activateKeepAwake('navigation');     // independent hold
deactivateKeepAwake('download');     // screen still awake — 'navigation' holds it
deactivateKeepAwake('navigation');   // now the screen can sleep

isKeepAwakeActive();                 // true if any tag is active
isKeepAwakeActive('download');       // per-tag query
getActiveKeepAwakeTags();            // ['navigation', ...] — great for debugging
deactivateAllKeepAwake();            // nuke every hold
isKeepAwakeAvailable();              // false only on web without the Wake Lock API

Calling activateKeepAwake() with no tag uses a shared 'default' tag, matching the old react-native-keep-awake behavior.

Component (drop-in for the deprecated package)

import KeepAwake from 'react-native-stay-awake';

// declarative
<KeepAwake />
<KeepAwake tag="player" enabled={isPlaying} />

// old-style statics still work
KeepAwake.activate();
KeepAwake.deactivate();

Web

On web the library uses the Screen Wake Lock API. The browser releases wake locks when the tab is hidden; this library re-acquires the lock automatically when the tab becomes visible again, so you don't have to handle visibilitychange yourself.

You can observe OS/browser-initiated releases (battery saver, tab hidden):

import { addKeepAwakeReleasedListener } from 'react-native-stay-awake';

const sub = addKeepAwakeReleasedListener(() => {
  console.log('wake lock was released by the platform');
});
sub.remove();

In unsupported browsers every call is a safe no-op (isKeepAwakeAvailable() returns false).

API reference

| Export | Description | | --- | --- | | useKeepAwake(tag?, { enabled? }) | Keep the screen awake while the component is mounted. | | <KeepAwake tag? enabled? /> | Component version; renders nothing. Default export. | | activateKeepAwake(tag?) | Add a hold for tag (default 'default'). | | deactivateKeepAwake(tag?) | Release the hold for tag. Screen sleeps when no holds remain. | | deactivateAllKeepAwake() | Release every hold. | | isKeepAwakeActive(tag?) | Whether any hold (or a specific tag) is active. | | getActiveKeepAwakeTags() | List of active tags. | | isKeepAwakeAvailable() | Whether the platform can keep the screen awake. | | addKeepAwakeReleasedListener(cb) | Web only: platform released the lock. Returns { remove() }. |

Migrating

From react-native-keep-awake (deprecated): the default export is a drop-in — <KeepAwake />, KeepAwake.activate(), and KeepAwake.deactivate() all work unchanged. Just swap the import:

- import KeepAwake from 'react-native-keep-awake';
+ import KeepAwake from 'react-native-stay-awake';

From expo-keep-awake: same tag model, but the API is synchronous — no promises to await, and deactivating an unknown tag is a safe no-op instead of a thrown error:

- import { useKeepAwake, activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
+ import { useKeepAwake, activateKeepAwake, deactivateKeepAwake } from 'react-native-stay-awake';

  useKeepAwake();                 // unchanged
- await activateKeepAwakeAsync('tag');
+ activateKeepAwake('tag');

Testing with Jest

A standalone mock ships with the package (old package's #33). It mirrors the real reference-counting logic in memory, so isKeepAwakeActive() assertions work in tests:

{
  "jest": {
    "moduleNameMapper": {
      "^react-native-stay-awake$": "react-native-stay-awake/jest/mock"
    }
  }
}

How it works

  • iOS / tvOS / visionOSUIApplication.isIdleTimerDisabled, always set on the main thread. The logic is written in Swift (StayAwakeImpl.swift); a thin ObjC++ shim conforms to the codegen'd TurboModule spec and forwards to it. Reset automatically when the React instance reloads, so a Fast Refresh never leaves your screen pinned awake.
  • AndroidFLAG_KEEP_SCREEN_ON on the current activity's window, applied on the UI thread. Null-activity safe (no startup crashes), and the flag is re-applied on onHostResume, so it survives activity recreation and multi-activity apps. No WAKE_LOCK permission needed — the window flag is permission-free.
  • Webnavigator.wakeLock.request('screen') with automatic re-acquisition on visibilitychange.
  • Reference counting lives in JS and is shared across all platforms, so behavior is identical everywhere; the native side is a dumb, stateless on/off switch that also cleans up after itself on reload (invalidate).

Lessons from the deprecated package

This library was designed around the actual issue history of react-native-keep-awake:

| Old issue | Fixed here by | | --- | --- | | #81 New Architecture support | TurboModule with codegen | | #44 Multiple <KeepAwake /> components fight each other | Tag-based reference counting | | #42 No way to query activity status | isKeepAwakeActive(), getActiveKeepAwakeTags() | | #68, #34 iOS crash: UI API called from background thread | Always dispatched to the main thread | | #15, #62 Android state lost after backgrounding / activity recreation | Flag re-applied on onHostResume | | #63 Idempotency undocumented | Documented tag semantics + tests | | #71, #67 Missing/broken TypeScript types | Written in TypeScript | | #52 StrictMode-unsafe lifecycle | Hooks (useEffect) throughout | | #66 iOS idle timer leaks across reloads ("always active") | Native invalidate() resets state on every reload | | #33 Jest mock support | react-native-stay-awake/jest mock | | #21#23 tvOS link failures, manual linking pain | Autolinking; tvOS/visionOS in the podspec |

Contributing

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

License

MIT