Back to Home

react-native-device-thermal

by Isaías Chávez

Monitor the thermal state of your iOS and Android devices in real-time with React Native.

Features

  • 🌡️ Get current thermal state of the device
  • 📊 Receive real-time thermal state change events
  • 🔥 Cross-platform support (iOS 11+ and Android 10+)
  • ⚡ Built with TurboModules and the New Architecture
  • 📱 Supports both new and legacy React Native architectures
  • 🎯 Fully typed TypeScript API

Platform Requirements

PlatformMinimum VersionAPI
iOSiOS 11.0NSProcessInfo.thermalState
AndroidAndroid 10 (API 29)PowerManager.currentThermalStatus

Installation

npm install react-native-device-thermal

or

yarn add react-native-device-thermal

iOS

cd ios && pod install

Android

No additional steps required.

API Reference

Methods

isThermalMonitoringAvailable(): Promise<boolean>

Check if thermal monitoring is available on the current device.

Returns: Promise<boolean> - true if available, false otherwise.

Example:

import { isThermalMonitoringAvailable } from 'react-native-device-thermal';

const isAvailable = await isThermalMonitoringAvailable();
console.log('Thermal monitoring available:', isAvailable);

getThermalState(): Promise<ThermalState>

Get the current thermal state of the device.

Returns: Promise<ThermalState> - The current thermal state.

Example:

import { getThermalState } from 'react-native-device-thermal';

const state = await getThermalState();
console.log('Current thermal state:', state);
// 'nominal', 'fair', 'serious', 'critical', or 'unknown'

getThermalInfo(): Promise<ThermalEvent>

Get detailed thermal information including the platform-specific state.

Returns: Promise<ThermalEvent> - Detailed thermal information.

Example:

import { getThermalInfo } from 'react-native-device-thermal';

const info = await getThermalInfo();
console.log('Thermal info:', info);
// {
//   state: 'nominal',
//   platformState: 'THERMAL_STATUS_NONE', // Android
//   temperature: null
// }

addThermalStateListener(listener)

Listen to thermal state changes in real-time.

Parameters:

  • listener - Callback function that receives ThermalEvent when the thermal state changes

Returns: EmitterSubscription - Subscription object with a remove() method

Example:

import { addThermalStateListener } from 'react-native-device-thermal';

const subscription = addThermalStateListener((event) => {
  console.log('Thermal state changed:', event.state);
  console.log('Platform state:', event.platformState);
});

// Later, to stop listening:
subscription.remove();

Types

ThermalState

Normalized thermal states across platforms:

type ThermalState =
  | 'unknown'   // Unable to determine or not supported
  | 'nominal'   // Normal temperature
  | 'fair'      // Slightly elevated, no action needed
  | 'serious'   // High temperature, reduce performance
  | 'critical'  // Very high temperature, immediate action needed

ThermalEvent

type ThermalEvent = {
  state: ThermalState;        // Normalized state
  platformState: string;      // Platform-specific state string
  temperature?: number | null; // Temperature in Celsius (currently always null)
}

Platform-Specific States

iOS (NSProcessInfoThermalState)

iOS StateNormalized StateDescription
NSProcessInfoThermalStateNominalnominalNo thermal issues
NSProcessInfoThermalStateFairfairSlightly elevated
NSProcessInfoThermalStateSeriousseriousThermal pressure, reduce work
NSProcessInfoThermalStateCriticalcriticalHigh thermal pressure, reduce work significantly

Android (PowerManager.ThermalStatus)

Android StateNormalized StateDescription
THERMAL_STATUS_NONE (0)nominalNo thermal issues
THERMAL_STATUS_LIGHT (1)fairLight thermal throttling
THERMAL_STATUS_MODERATE (2)fairModerate thermal throttling
THERMAL_STATUS_SEVERE (3)seriousSevere thermal throttling
THERMAL_STATUS_CRITICAL (4)criticalCritical thermal state
THERMAL_STATUS_EMERGENCY (5)criticalEmergency thermal state
THERMAL_STATUS_SHUTDOWN (6)criticalDevice about to shutdown

Usage Example

import React, { useState, useEffect } from 'react';
import { View, Text, Button } from 'react-native';
import {
  isThermalMonitoringAvailable,
  getThermalState,
  getThermalInfo,
  addThermalStateListener,
  type ThermalState,
  type ThermalEvent,
} from 'react-native-device-thermal';

export default function App() {
  const [isAvailable, setIsAvailable] = useState(false);
  const [thermalState, setThermalState] = useState<ThermalState>('unknown');
  const [isListening, setIsListening] = useState(false);

  useEffect(() => {
    checkAvailability();
  }, []);

  useEffect(() => {
    if (!isListening) return;

    const subscription = addThermalStateListener((event: ThermalEvent) => {
      console.log('Thermal state changed:', event);
      setThermalState(event.state);
    });

    return () => {
      subscription.remove();
    };
  }, [isListening]);

  const checkAvailability = async () => {
    const available = await isThermalMonitoringAvailable();
    setIsAvailable(available);
  };

  const fetchState = async () => {
    const state = await getThermalState();
    setThermalState(state);
  };

  const fetchInfo = async () => {
    const info = await getThermalInfo();
    console.log('Thermal info:', info);
    setThermalState(info.state);
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', padding: 20 }}>
      <Text>Available: {isAvailable ? 'Yes' : 'No'}</Text>
      <Text>State: {thermalState}</Text>

      <Button title="Get State" onPress={fetchState} />
      <Button title="Get Info" onPress={fetchInfo} />
      <Button
        title={isListening ? 'Stop Listening' : 'Start Listening'}
        onPress={() => setIsListening(!isListening)}
      />
    </View>
  );
}

Practical Use Cases

1. Performance Optimization

Reduce app workload when device is overheating:

const subscription = addThermalStateListener((event) => {
  if (event.state === 'serious' || event.state === 'critical') {
    // Reduce frame rate, disable animations, pause background tasks
    pauseHeavyOperations();
  } else if (event.state === 'nominal') {
    // Resume normal operations
    resumeHeavyOperations();
  }
});

2. User Notifications

Warn users about thermal issues:

const state = await getThermalState();

if (state === 'critical') {
  Alert.alert(
    'Device Overheating',
    'Your device is very hot. Consider closing some apps or letting it cool down.'
  );
}

3. Gaming & AR Apps

Adjust graphics quality based on thermal state:

addThermalStateListener((event) => {
  switch (event.state) {
    case 'nominal':
      setGraphicsQuality('ultra');
      break;
    case 'fair':
      setGraphicsQuality('high');
      break;
    case 'serious':
      setGraphicsQuality('medium');
      break;
    case 'critical':
      setGraphicsQuality('low');
      break;
  }
});

4. Video Recording Apps

Adjust video quality or stop recording:

addThermalStateListener((event) => {
  if (event.state === 'critical') {
    // Stop 4K recording, switch to 1080p
    downgradeVideoQuality();
  }
});

Limitations

  • Temperature reading: Both iOS and Android do not expose actual temperature values through their public APIs. The temperature field will always be null.
  • iOS: Thermal monitoring requires iOS 11 or later.
  • Android: Thermal monitoring requires Android 10 (API 29) or later.
  • Emulators: Thermal states may not work properly on emulators/simulators. Test on real devices.

Troubleshooting

iOS: Module not found

Make sure you've installed pods:

cd ios && pod install

Android: Build errors

Ensure your minSdkVersion in android/build.gradle is at least 21 (though thermal APIs require API 29).

No events received

  • Make sure you're testing on a real device, not an emulator
  • Verify thermal monitoring is available: await isThermalMonitoringAvailable()
  • Check that you're calling addListener before the subscription

License

MIT


Made with create-react-native-library