A universal module that gets physical information about the device running the application
npx @tessl/cli install tessl/npm-expo-device@8.0.0Expo Device is a universal module that provides comprehensive device information and capabilities detection for React Native and Expo applications across iOS, Android, and web platforms. It offers both synchronous properties and asynchronous methods to retrieve detailed device specifications including hardware details, operating system information, device classification, and system capabilities.
npx expo install expo-deviceFor bare React Native projects, ensure you have installed and configured the expo package before installing expo-device.
import * as Device from 'expo-device';
// Or import specific items
import { DeviceType, isDevice, brand, getDeviceTypeAsync } from 'expo-device';For CommonJS:
const Device = require('expo-device');
// Or destructure specific items
const { DeviceType, isDevice, brand, getDeviceTypeAsync } = require('expo-device');import * as Device from 'expo-device';
// Check if running on a real device
console.log('Is real device:', Device.isDevice);
// Get basic device information
console.log('Device brand:', Device.brand);
console.log('Device manufacturer:', Device.manufacturer);
console.log('Device model:', Device.modelName);
console.log('Device type:', Device.deviceType);
// Get OS information
console.log('OS Name:', Device.osName);
console.log('OS Version:', Device.osVersion);
// Use async methods for additional capabilities
const deviceType = await Device.getDeviceTypeAsync();
const uptime = await Device.getUptimeAsync();
const isRooted = await Device.isRootedExperimentalAsync();
console.log('Device type (async):', deviceType);
console.log('Device uptime:', uptime);
console.log('Is rooted/jailbroken:', isRooted);Expo Device is built around several key components:
Synchronous properties providing immediate access to device information. Most properties return platform-specific values with documented fallbacks for unsupported platforms.
// Device detection
const isDevice: boolean;
// Device identification
const brand: string | null;
const manufacturer: string | null;
const modelId: string | null;
const modelName: string | null;
const designName: string | null;
const productName: string | null;
const deviceName: string | null;
// Device classification
const deviceType: DeviceType | null;
const deviceYearClass: number | null;
// Hardware specifications
const totalMemory: number | null;
const supportedCpuArchitectures: string[] | null;
// Operating system information
const osName: string | null;
const osVersion: string | null;
const osBuildId: string | null;
const osInternalBuildId: string | null;
const osBuildFingerprint: string | null;
const platformApiLevel: number | null;Device type determination with platform-specific logic.
enum DeviceType {
UNKNOWN = 0,
PHONE = 1,
TABLET = 2,
DESKTOP = 3,
TV = 4
}
/**
* Asynchronously checks the device type
* @returns Promise resolving to DeviceType enum value
*/
function getDeviceTypeAsync(): Promise<DeviceType>;Platform-specific behavior:
Methods for querying system-level information and capabilities.
/**
* Gets uptime since last reboot in milliseconds
* Android devices do not count time spent in deep sleep
* @returns Promise resolving to milliseconds since last reboot
* @platform ios, android
*/
function getUptimeAsync(): Promise<number>;
/**
* Returns maximum memory Java VM will attempt to use
* Returns Number.MAX_SAFE_INTEGER if no inherent limit
* @returns Promise resolving to max available memory in bytes
* @platform android
*/
function getMaxMemoryAsync(): Promise<number>;Methods for detecting device security state and installation permissions.
/**
* Experimental method to detect if device is rooted/jailbroken
* Not completely reliable due to bypass methods
* @returns Promise resolving to boolean indicating root/jailbreak status
* @platform ios, android (always false on web)
*/
function isRootedExperimentalAsync(): Promise<boolean>;
/**
* Checks if applications can be installed outside the default app store
* Requires REQUEST_INSTALL_PACKAGES permission in app.json
* @returns Promise resolving to boolean indicating sideloading permission
* @platform android
*/
function isSideLoadingEnabledAsync(): Promise<boolean>;Android-specific methods for querying system features and capabilities.
/**
* Gets list of all available system features
* @returns Promise resolving to array of platform-specific feature names
* @platform android (empty array on ios/web)
*/
function getPlatformFeaturesAsync(): Promise<string[]>;
/**
* Checks if device has a specific system feature
* @param feature Platform-specific feature name to check
* @returns Promise resolving to boolean indicating feature availability
* @platform android (false on ios/web)
*/
function hasPlatformFeatureAsync(feature: string): Promise<boolean>;enum DeviceType {
/**
* An unrecognized device type
*/
UNKNOWN = 0,
/**
* Mobile phone handsets, typically with a touch screen and held in one hand
*/
PHONE = 1,
/**
* Tablet computers, typically with a touch screen that is larger than a usual phone
*/
TABLET = 2,
/**
* Desktop or laptop computers, typically with a keyboard and mouse
*/
DESKTOP = 3,
/**
* Device with TV-based interfaces
*/
TV = 4
}| Property/Method | iOS | Android | Web | Notes |
|---|---|---|---|---|
isDevice | ✅ | ✅ | ✅ | Always true on web |
brand | ✅ | ✅ | ❌ | Always null on web |
manufacturer | ✅ | ✅ | ✅ | From UA parser on web |
modelId | ✅ | ❌ | ❌ | iOS only |
modelName | ✅ | ✅ | ✅ | From UA parser on web |
designName | ❌ | ✅ | ❌ | Android only |
productName | ❌ | ✅ | ❌ | Android only |
deviceType | ✅ | ✅ | ✅ | Screen-based detection on Android |
deviceYearClass | ✅ | ✅ | ❌ | Always null on web |
totalMemory | ✅ | ✅ | ✅* | Via navigator.deviceMemory on web |
supportedCpuArchitectures | ✅ | ✅ | ✅* | From UA parser on web |
osName | ✅ | ✅ | ✅ | From UA parser on web |
osVersion | ✅ | ✅ | ✅ | From UA parser on web |
osBuildId | ✅ | ✅ | ❌ | Always null on web |
osInternalBuildId | ✅ | ✅ | ❌ | Always null on web |
osBuildFingerprint | ❌ | ✅ | ❌ | Android only |
platformApiLevel | ❌ | ✅ | ❌ | Android only |
deviceName | ✅ | ✅ | ❌ | Always null on web |
getDeviceTypeAsync() | ✅ | ✅ | ✅ | Same as deviceType property |
getUptimeAsync() | ✅ | ✅ | ❌ | Not available on web |
getMaxMemoryAsync() | ❌ | ✅ | ❌ | Android only |
isRootedExperimentalAsync() | ✅ | ✅ | ✅ | Always false on web |
isSideLoadingEnabledAsync() | ❌ | ✅ | ❌ | Android only |
getPlatformFeaturesAsync() | ✅* | ✅ | ✅* | Empty array on iOS/web |
hasPlatformFeatureAsync() | ✅* | ✅ | ✅* | Always false on iOS/web |
*Limited functionality or fallback behavior
Methods that are unavailable on the current platform will throw UnavailabilityError from expo-modules-core:
import { UnavailabilityError } from 'expo-modules-core';
try {
const maxMemory = await Device.getMaxMemoryAsync();
} catch (error) {
if (error instanceof UnavailabilityError) {
console.log('getMaxMemoryAsync not available on this platform');
}
}import { DeviceType, deviceType, getDeviceTypeAsync } from 'expo-device';
// Synchronous (immediate)
if (deviceType === DeviceType.TABLET) {
// Show tablet-optimized UI
}
// Asynchronous (same result, but as Promise)
const type = await getDeviceTypeAsync();
if (type === DeviceType.PHONE) {
// Show phone-optimized UI
}import * as Device from 'expo-device';
import { Platform } from 'react-native';
// Check Android-specific information
if (Platform.OS === 'android') {
console.log('Design name:', Device.designName);
console.log('Product name:', Device.productName);
console.log('Platform API level:', Device.platformApiLevel);
// Check for specific Android features
const hasNFC = await Device.hasPlatformFeatureAsync('android.hardware.nfc');
console.log('Has NFC:', hasNFC);
}
// Check iOS-specific information
if (Platform.OS === 'ios') {
console.log('Model ID:', Device.modelId);
console.log('Device name:', Device.deviceName);
}import * as Device from 'expo-device';
import { Platform } from 'react-native';
// Total device memory
console.log('Total memory:', Device.totalMemory, 'bytes');
// Device performance classification
console.log('Device year class:', Device.deviceYearClass);
// CPU architectures
console.log('Supported architectures:', Device.supportedCpuArchitectures);
// Android: Get JVM max memory
if (Platform.OS === 'android') {
const maxMemory = await Device.getMaxMemoryAsync();
console.log('Max JVM memory:', maxMemory, 'bytes');
}import * as Device from 'expo-device';
// Check if device is rooted/jailbroken (experimental)
const isRooted = await Device.isRootedExperimentalAsync();
if (isRooted) {
console.warn('Device appears to be rooted/jailbroken');
}
// Check sideloading permissions (Android)
if (Platform.OS === 'android') {
const canSideload = await Device.isSideLoadingEnabledAsync();
console.log('Sideloading enabled:', canSideload);
}