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-energy-aware

v0.2.2

Published

React Native hooks and components that adapt to battery, low power, and thermal state

Readme

⚡ react-native-energy-aware

React Native hooks that adapt your app to battery, thermal, and power save state — automatically.

Stop draining your users' battery. Stop ignoring thermal warnings. One hook, zero boilerplate.

npm version MIT License Platform iOS Platform Android


Why?

Most apps ignore the device energy state entirely. They animate at 60 FPS on a 5% battery, run heavy syncs when the device is overheating, and poll every 5 seconds regardless of power save mode.

react-native-energy-aware gives you a simple API to make your app a good energy citizen — without having to deal with UIDevice, NSProcessInfo, PowerManager, or BroadcastReceiver yourself.


Installation

npm install react-native-energy-aware
# or
yarn add react-native-energy-aware

iOS — run pod install after installing:

cd ios && pod install

Requires React Native 0.75+. Supports both New Architecture (TurboModule) and Old Architecture natively.


Quick start

import { useEnergyState } from 'react-native-energy-aware';

export function MyScreen() {
  const { energyMode, batteryLevel, thermalState } = useEnergyState();

  if (energyMode === 'critical') {
    return <LightweightView />;
  }

  return <FullFeaturedView />;
}

That's it. energyMode is a single computed value that combines battery level, low power mode, and thermal state — so you don't have to.


API

useEnergyState() — the main hook

Returns the full energy state of the device, updated in real time.

const {
  batteryLevel,    // number — 0.0 to 1.0 (-1 if unknown)
  batteryState,    // 'charging' | 'unplugged' | 'full' | 'unknown'
  isLowPowerMode,  // boolean
  thermalState,    // 'nominal' | 'fair' | 'serious' | 'critical'
  energyMode,      // 'normal' | 'saver' | 'critical' | 'overheating'
} = useEnergyState();

energyMode logic

| Mode | Triggers | |---|---| | overheating | thermalState is serious or critical | | critical | battery < 15%, or (low power + battery < 20%) — not charging | | saver | low power mode on, or thermalState fair, or battery < 30% | | normal | everything else |


Derived hooks

For most use cases, you don't even need energyMode — just use the purpose-built hooks:

useShouldReduceAnimations()

import { useShouldReduceAnimations } from 'react-native-energy-aware';

function MyComponent() {
  const reduceAnimations = useShouldReduceAnimations();

  return reduceAnimations
    ? <StaticBanner />
    : <AnimatedBanner />;
}

Returns true in saver, critical, or overheating mode.

useShouldReduceQuality()

import { useShouldReduceQuality } from 'react-native-energy-aware';

function Feed() {
  const reduceQuality = useShouldReduceQuality();

  return (
    <Image
      source={{ uri: reduceQuality ? thumbnailUrl : hdUrl }}
    />
  );
}

Returns true in critical or overheating mode.

useRecommendedFPS()

import { useRecommendedFPS } from 'react-native-energy-aware';

function GameLoop() {
  const fps = useRecommendedFPS(); // 60 | 30 | 15

  useEffect(() => {
    startLoop({ targetFPS: fps });
  }, [fps]);
}

| Mode | FPS | |---|---| | normal | 60 | | saver | 30 | | critical / overheating | 15 |

useCanRunExpensiveTask()

import { useCanRunExpensiveTask } from 'react-native-energy-aware';

function SyncButton() {
  const canSync = useCanRunExpensiveTask();

  return (
    <Button
      onPress={canSync ? runHeavySync : showDeferredMessage}
      title={canSync ? 'Sync now' : 'Sync deferred (low battery)'}
    />
  );
}

Returns true only in normal mode. Use this to gate ML inference, large uploads, image processing, etc.

useAdaptiveInterval(config)

import { useAdaptiveInterval } from 'react-native-energy-aware';

function Feed() {
  const interval = useAdaptiveInterval({
    normal: 5000,   // poll every 5s normally
    saver: 30000,   // 30s in power save mode
    critical: 60000, // 60s when battery is critical
  });

  useEffect(() => {
    const id = setInterval(fetchData, interval);
    return () => clearInterval(id);
  }, [interval]);
}

Returns the appropriate interval in milliseconds based on energyMode. overheating uses the critical value.


Components

<EnergyAwareAnimation>

Renders children in normal mode, fallback when animations should be reduced. Works with any animation library — Lottie, Reanimated, Skia, etc.

import { EnergyAwareAnimation } from 'react-native-energy-aware';

<EnergyAwareAnimation fallback={<StaticBanner />}>
  <LottieView source={animation} autoPlay loop />
</EnergyAwareAnimation>

<EnergyDebugOverlay>

Debug overlay that displays real-time energy state. Wrap it in __DEV__ so it never ships to production.

import { EnergyDebugOverlay } from 'react-native-energy-aware';

// In your root component:
{__DEV__ && <EnergyDebugOverlay position="bottom-right" />}

Props: position'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' (default: 'bottom-right')


Real-world example

import {
  useEnergyState,
  useRecommendedFPS,
  useShouldReduceAnimations,
  useCanRunExpensiveTask,
} from 'react-native-energy-aware';

export function VideoFeed() {
  const { energyMode, batteryLevel } = useEnergyState();
  const fps = useRecommendedFPS();
  const reduceAnimations = useShouldReduceAnimations();
  const canRunHeavy = useCanRunExpensiveTask();

  return (
    <View>
      {energyMode === 'overheating' && (
        <Banner message="⚠️ Device is hot — quality reduced" />
      )}

      <VideoPlayer
        targetFPS={fps}
        quality={energyMode === 'normal' ? 'high' : 'low'}
        autoplay={energyMode !== 'critical'}
      />

      {reduceAnimations
        ? <StaticRecommendations />
        : <AnimatedRecommendations />}

      {canRunHeavy && (
        <Button onPress={runMLRecommendations} title="Get AI picks" />
      )}

      <Text>{Math.round(batteryLevel * 100)}% battery</Text>
    </View>
  );
}

Platform support

| Feature | iOS | Android | |---|---|---| | Battery level | ✅ UIDevice.batteryLevel | ✅ BatteryManager | | Battery state | ✅ UIDevice.batteryState | ✅ ACTION_BATTERY_CHANGED | | Low power mode | ✅ NSProcessInfo.isLowPowerModeEnabled | ✅ PowerManager.isPowerSaveMode | | Thermal state | ✅ NSProcessInfo.thermalState | ✅ PowerManager.currentThermalStatus (API 29+) | | Real-time updates | ✅ | ✅ |

On Android < API 29, thermalState always returns 'nominal' — there is no thermal API on older versions.


Architecture

Built on the New Architecture (TurboModule + Codegen) with native Old Architecture support (RCT_EXPORT_MODULE / ReactContextBaseJavaModule).

  • Native observers are ref-counted — multiple useEnergyState instances share a single native subscription.
  • No context or provider required for v0.1 — hooks are self-contained.

Roadmap

  • v1.0<EnergyProvider> context, EnergyAwareImage, EnergyAwareVideo, deferred task runner, plugin system for Reanimated / FlashList / Vision Camera / TanStack Query
  • v1.1+ — Energy budget tracker, background task throttling, carbon-aware scheduling

Contributing

License

MIT © ClemDelb