π High-performance battery monitoring for React Native built with Nitro Modules.
This module provides comprehensive battery monitoring functionality for React Native applications. Monitor battery level, charging state, and low power mode with real-time updates and listeners, all built with Nitro Modules for optimal native performance and zero-bridge overhead.
- β‘ High-performance native implementation using Nitro Modules
- π Real-time battery level monitoring
- π Charging state detection (charging, discharging, full, unknown)
- οΏ½ Low power mode detection and notifications
- π― Event listeners for battery state changes
- π± Cross-platform support (iOS & Android)
- π Zero-bridge overhead with direct native calls
- π‘οΈ Memory-safe with automatic cleanup and proper listener management
- React Native >= 0.76
- Node >= 18
react-native-nitro-modulesmust be installed (Nitro runtime)
npm install react-native-nitro-battery react-native-nitro-modules
# or
yarn add react-native-nitro-battery react-native-nitro-modulesNo additional configuration required. The module automatically enables battery monitoring when initialized.
Add battery monitoring permission to your android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Optional: For more detailed battery information -->
<uses-permission android:name="android.permission.BATTERY_STATS" />
<application
android:name=".MainApplication"
android:allowBackup="false"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/LaunchTheme">
<!-- Your existing activity configuration -->
</activity>
</application>
</manifest>import {
NitroBattery,
addBatteryStateListener,
addLowPowerListener,
getLevel,
isCharging
} from 'react-native-nitro-battery'
// Get current battery level (0-100)
const batteryLevel = getLevel()
console.log(`Battery level: ${batteryLevel}%`)
// Check if device is charging
const charging = isCharging()
console.log(`Is charging: ${charging}`)
const subscription = state => {
console.log('Battery state changed:', state);
};
// Listen to battery state changes
addBatteryStateListener(subscription);
// Listen to low power mode activation
removeBatteryStateListener(subscription);
// Don't forget to remove listeners when done
// removeBatteryStateListener
// removeLowPowerListenerThe main battery monitoring module providing direct access to native functionality.
Returns the current battery level as a percentage.
- Returns: Battery level from 0-100, or -1 if unavailable
const level = getLevel()
console.log(`Battery: ${level}%`)Checks if the device is currently charging.
- Returns:
trueif charging or full,falseotherwise
const charging = isCharging()
if (charging) {
console.log('Device is charging')
}Gets the current battery state.
- Returns: One of:
'charging','discharging','full','unknown'
const state = NitroBattery.getBatteryState()
console.log(`Battery state: ${state}`)Checks if low power mode is currently enabled.
- Returns:
trueif low power mode is active
const lowPower = NitroBattery.isLowPowerModeEnabled()
if (lowPower) {
console.log('Device is in low power mode')
}Adds a listener for battery state changes.
- listener: Callback function that receives the new battery state
const listenerId = addBatteryStateListener((state) => {
console.log(`Battery state: ${state}`)
})Removes a battery state listener.
- listener: Callback function that receives the new battery state
removeBatteryStateListener(listenerId)Adds a listener for low power mode activation.
- listener: Callback function called when low power mode is enabled
addLowPowerListener(() => {
console.log('Low power mode activated!')
})Removes a low power mode listener.
- listener: Callback function called when low power mode is enabled
removeLowPowerListener(listenerId)Removes all registered listeners. Useful for cleanup.
NitroBattery.removeAllListeners()import React, { useEffect, useState } from 'react'
import { View, Text, Alert } from 'react-native'
import {
getLevel,
isCharging,
addBatteryStateListener,
addLowPowerListener,
removeBatteryStateListener,
removeLowPowerListener
} from 'react-native-nitro-battery'
const BatteryMonitor = () => {
const [batteryLevel, setBatteryLevel] = useState(0)
const [charging, setCharging] = useState(false)
const [batteryState, setBatteryState] = useState('unknown')
useEffect(() => {
// Get initial values
setBatteryLevel(getLevel())
setCharging(isCharging())
}, [])
useEffect(() => {
const subscription = state => {
console.log('Battery state changed:', state);
};
addBatteryStateListener(subscription);
return () => {
removeBatteryStateListener(subscription);
};
}, []);
const getBatteryColor = () => {
if (charging) return '#4CAF50' // Green when charging
if (batteryLevel < 20) return '#F44336' // Red when low
if (batteryLevel < 50) return '#FF9800' // Orange when medium
return '#4CAF50' // Green when good
}
const getBatteryIcon = () => {
if (charging) return 'π'
if (batteryLevel < 20) return 'πͺ«'
return 'π'
}
return (
<View style={{ padding: 20, alignItems: 'center' }}>
<Text style={{ fontSize: 48 }}>{getBatteryIcon()}</Text>
<Text style={{
fontSize: 32,
fontWeight: 'bold',
color: getBatteryColor()
}}>
{batteryLevel}%
</Text>
<Text style={{ fontSize: 18, marginTop: 10 }}>
Status: {charging ? 'Charging' : 'Not Charging'}
</Text>
<Text style={{ fontSize: 16, marginTop: 5, color: '#666' }}>
State: {batteryState}
</Text>
</View>
)
}import { useState, useEffect, useCallback } from 'react'
import {
getLevel,
isCharging,
addBatteryStateListener,
addLowPowerListener,
removeBatteryStateListener,
removeLowPowerListener,
NitroBattery
} from 'react-native-nitro-battery'
export interface BatteryInfo {
level: number
isCharging: boolean
state: string
isLowPowerMode: boolean
}
export const useBattery = () => {
const [batteryInfo, setBatteryInfo] = useState<BatteryInfo>({
level: getLevel(),
isCharging: isCharging(),
state: NitroBattery.getBatteryState(),
isLowPowerMode: NitroBattery.isLowPowerModeEnabled(),
})
const updateBatteryInfo = useCallback(() => {
setBatteryInfo({
level: getLevel(),
isCharging: isCharging(),
state: NitroBattery.getBatteryState(),
isLowPowerMode: NitroBattery.isLowPowerModeEnabled(),
})
}, [])
useEffect(() => {
const batteryListener = addBatteryStateListener((state) => {
updateBatteryInfo()
})
const lowPowerListener = addLowPowerListener(() => {
updateBatteryInfo()
})
return () => {
removeBatteryStateListener(batteryListener)
removeLowPowerListener(lowPowerListener)
}
}, [updateBatteryInfo])
return {
...batteryInfo,
refresh: updateBatteryInfo,
isLowBattery: batteryInfo.level < 20,
isCriticalBattery: batteryInfo.level < 10,
batteryHealth: batteryInfo.level > 80 ? 'excellent' :
batteryInfo.level > 50 ? 'good' :
batteryInfo.level > 20 ? 'fair' : 'poor'
}
}
// Usage in component
const BatteryStatus = () => {
const {
level,
isCharging,
state,
isLowPowerMode,
isLowBattery,
isCriticalBattery,
batteryHealth
} = useBattery()
return (
<View>
<Text>Battery: {level}%</Text>
<Text>Charging: {isCharging ? 'Yes' : 'No'}</Text>
<Text>State: {state}</Text>
<Text>Low Power Mode: {isLowPowerMode ? 'On' : 'Off'}</Text>
<Text>Health: {batteryHealth}</Text>
{isLowBattery && <Text style={{color: 'red'}}>β οΈ Low Battery</Text>}
{isCriticalBattery && <Text style={{color: 'red'}}>π¨ Critical Battery</Text>}
</View>
)
}Always clean up listeners to prevent memory leaks:
useEffect(() => {
const subscription = state => {
console.log('Battery state changed:', state);
};
addBatteryStateListener(subscription);
return () => {
removeBatteryStateListener(subscription);
};
}, []);- Battery monitoring has minimal performance impact
- Listeners are called on the main thread for UI updates
- Use throttling for frequent UI updates if needed
// Good: Throttled battery level updates
let lastUpdate = 0
const THROTTLE_MS = 1000 // Update UI max once per second
addBatteryStateListener((state) => {
const now = Date.now()
if (now - lastUpdate > THROTTLE_MS) {
updateUI(getLevel(), state)
lastUpdate = now
}
})try {
const level = getLevel()
if (level === -1) {
console.warn('Battery level unavailable')
// Handle unavailable battery info
} else {
// Use battery level normally
console.log(`Battery: ${level}%`)
}
} catch (error) {
console.error('Battery monitoring error:', error)
}Based on battery state, you can optimize your app's behavior:
addBatteryStateListener((state) => {
switch (state) {
case 'charging':
// Device is charging, safe to perform intensive tasks
enableHighPerformanceMode()
break
case 'discharging':
// On battery power, optimize for efficiency
enablePowerSavingMode()
break
case 'full':
// Battery full, can perform maintenance tasks
performMaintenanceTasks()
break
}
})
addLowPowerListener(() => {
// User enabled low power mode, reduce app functionality
enableMinimalMode()
pauseNonEssentialServices()
})- β Full battery monitoring support
- β Real-time battery state changes
- β Low power mode detection (Android 5.0+)
- β Battery level accuracy within 1%
- β Works with all Android versions
- β Full battery monitoring support
- β Real-time battery state changes
- β Low power mode detection (iOS 9.0+)
- β Battery level accuracy within 1%
- β Automatic battery monitoring management
- This is normal on iOS Simulator (no battery)
- On real devices, ensure battery monitoring is enabled (handled automatically)
- Verify listeners are properly added and stored
- Check that listeners are removed in cleanup functions
- Ensure the app has proper permissions (Android)
- Always store listener IDs returned from add functions
- Remove listeners in component cleanup/unmount
// Before (react-native-battery)
import { getBatteryLevel, isCharging } from 'react-native-battery'
// After (react-native-nitro-battery)
import { getLevel, isCharging } from 'react-native-nitro-battery'
// Most APIs are similar or improved
const level = getLevel() // Instead of getBatteryLevel()
const charging = isCharging() // Same API// Before (typical pattern with other libraries)
import { BatteryManager } from 'some-battery-library'
BatteryManager.addEventListener('batteryLevelChange', callback)
// After (react-native-nitro-battery)
import { addBatteryStateListener, removeBatteryStateListener } from 'react-native-nitro-battery'
useEffect(() => {
const subscription = state => {
console.log('Battery state changed:', state);
};
addBatteryStateListener(subscription);
return () => {
removeBatteryStateListener(subscription);
};
}, []);// Listener function types
type BatteryListener = (state: string) => void
type LowPowerListener = () => void
// Main API interface
interface NitroBatterySpec {
getLevel(): number
isCharging(): boolean
getBatteryState(): string
isLowPowerModeEnabled(): boolean
addBatteryStateListener(listener: BatteryListener): string
removeBatteryStateListener(listener: BatteryListener): void
addLowPowerListener(listener: LowPowerListener): string
removeLowPowerListener(listener: LowPowerListener): void
}See CONTRIBUTING.md for contribution workflow.
When updating spec files in src/specs/*.nitro.ts, regenerate Nitro artifacts:
yarn nitrogenandroid/β Native Android implementation (Kotlin/Java)ios/β Native iOS implementation (Swift)src/β TypeScript source code and exportsnitrogen/β Generated Nitro artifacts (auto-generated)lib/β Compiled JavaScript output
Special thanks to the following projects that inspired this library:
- mrousavy/nitro β Nitro Modules architecture
MIT Β© ThΓ nh CΓ΄ng