Skip to content

Instantly share code, notes, and snippets.

@jrobinsonc
Last active July 10, 2025 14:12
Show Gist options
  • Save jrobinsonc/6ba25e3bc937db2972090b1689085595 to your computer and use it in GitHub Desktop.
Save jrobinsonc/6ba25e3bc937db2972090b1689085595 to your computer and use it in GitHub Desktop.
Show details about the device
import { Platform } from 'react-native';
export interface DeviceInfo {
platform: 'ios' | 'android' | 'web';
isIOS: boolean;
isAndroid: boolean;
isWeb: boolean;
isSimulator: boolean;
isEmulator: boolean;
isExpoApp: boolean;
isDevelopment: boolean;
deviceName?: string;
osVersion?: string;
}
/**
* Detects if the app is running in iOS Simulator
* This is a best-effort detection and may not be 100% reliable
*/
const isIOSSimulator = (): boolean => {
if (Platform.OS !== 'ios') return false;
// Check if we're in development mode
if (__DEV__) {
// In development, if we're on iOS and not on a physical device,
// we're likely in the simulator
return true;
}
return false;
};
/**
* Detects if the app is running in Android Emulator
* This is a best-effort detection and may not be 100% reliable
*/
const isAndroidEmulator = (): boolean => {
if (Platform.OS !== 'android') return false;
// Check if we're in development mode
if (__DEV__) {
// In development, if we're on Android and not on a physical device,
// we're likely in the emulator
return true;
}
return false;
};
/**
* Detects if the app is running in Expo Go app
* This is a best-effort detection based on environment variables and development mode
*/
const isExpoApp = (): boolean => {
// In development mode, if we're not in a simulator/emulator,
// we're likely running in Expo Go
if (__DEV__) {
const isSimulator = isIOSSimulator();
const isEmulator = isAndroidEmulator();
// If we're in dev mode but not in simulator/emulator, likely Expo Go
if (!isSimulator && !isEmulator) {
return true;
}
}
return false;
};
/**
* Gets comprehensive device information
*
* @example
* ```typescript
* import { getDeviceInfo } from '@/utils/deviceDetection';
*
* const deviceInfo = getDeviceInfo();
*
* if (deviceInfo.isSimulator) {
* console.log('Running in iOS Simulator');
* }
*
* if (deviceInfo.isExpoApp) {
* console.log('Running in Expo Go app');
* }
* ```
*/
export const getDeviceInfo = (): DeviceInfo => {
const platform = Platform.OS as 'ios' | 'android' | 'web';
const isSimulator = isIOSSimulator();
const isEmulator = isAndroidEmulator();
const isExpoAppRunning = isExpoApp();
// Safely get device name from Platform.constants
let deviceName: string | undefined;
if (Platform.OS === 'ios') {
const iosConstants = Platform.constants as Record<string, unknown>;
deviceName = iosConstants?.systemName as string | undefined;
}
return {
platform,
isIOS: platform === 'ios',
isAndroid: platform === 'android',
isWeb: platform === 'web',
isSimulator,
isEmulator,
isExpoApp: isExpoAppRunning,
isDevelopment: __DEV__,
deviceName,
osVersion: Platform.Version?.toString(),
};
};
/**
* Quick check if running in iOS Simulator
*
* @example
* ```typescript
* import { isIOSSimulatorRunning } from '@/utils/deviceDetection';
*
* if (isIOSSimulatorRunning()) {
* // Do something specific for iOS Simulator
* }
* ```
*/
export const isIOSSimulatorRunning = (): boolean => {
return getDeviceInfo().isSimulator;
};
/**
* Quick check if running in Android Emulator
*
* @example
* ```typescript
* import { isAndroidEmulatorRunning } from '@/utils/deviceDetection';
*
* if (isAndroidEmulatorRunning()) {
* // Do something specific for Android Emulator
* }
* ```
*/
export const isAndroidEmulatorRunning = (): boolean => {
return getDeviceInfo().isEmulator;
};
/**
* Quick check if running in Expo Go app
*
* @example
* ```typescript
* import { isExpoGoRunning } from '@/utils/deviceDetection';
*
* if (isExpoGoRunning()) {
* // Do something specific for Expo Go
* }
* ```
*/
export const isExpoGoRunning = (): boolean => {
return getDeviceInfo().isExpoApp;
};
/**
* Quick check if running in any simulator/emulator
*
* @example
* ```typescript
* import { isSimulatorOrEmulator } from '@/utils/deviceDetection';
*
* if (isSimulatorOrEmulator()) {
* // Do something for any simulator/emulator
* }
* ```
*/
export const isSimulatorOrEmulator = (): boolean => {
const info = getDeviceInfo();
return info.isSimulator || info.isEmulator;
};
/**
* Get a human-readable description of the current environment
*
* @example
* ```typescript
* import { getEnvironmentDescription } from '@/utils/deviceDetection';
*
* const env = getEnvironmentDescription();
* console.log(`Running in: ${env}`); // "Running in: iOS Simulator"
* ```
*/
export const getEnvironmentDescription = (): string => {
const info = getDeviceInfo();
if (info.isWeb) {
return 'Web Browser';
}
if (info.isExpoApp) {
return 'Expo Go App';
}
if (info.isSimulator) {
return 'iOS Simulator';
}
if (info.isEmulator) {
return 'Android Emulator';
}
if (info.isIOS) {
return 'iOS Device';
}
if (info.isAndroid) {
return 'Android Device';
}
return 'Unknown Environment';
};
/**
* Log device information to console (useful for debugging)
*
* @example
* ```typescript
* import { logDeviceInfo } from '@/utils/deviceDetection';
*
* // Log all device information to console
* logDeviceInfo();
* ```
*/
export const logDeviceInfo = (): void => {
const info = getDeviceInfo();
console.log('🔍 Device Information:', {
environment: getEnvironmentDescription(),
platform: info.platform,
isDevelopment: info.isDevelopment,
deviceName: info.deviceName,
osVersion: info.osVersion,
});
};
import Constants from 'expo-constants';
import * as Device from 'expo-device';
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import {
getDeviceInfo,
getEnvironmentDescription,
isExpoGoRunning,
isIOSSimulatorRunning,
} from './deviceDetection';
interface DeviceInfoDisplayProps {
showDetails?: boolean;
}
export const DeviceInfoDisplay: React.FC<DeviceInfoDisplayProps> = ({
showDetails = false,
}) => {
const deviceInfo = getDeviceInfo();
const environment = getEnvironmentDescription();
const isSimulator = isIOSSimulatorRunning();
const isExpoApp = isExpoGoRunning();
return (
<View style={styles.container}>
<Text style={styles.title}>Device Information</Text>
<Text style={styles.text}>
Device:{' '}
<Text style={styles.boldText}>
{Device.manufacturer}: {Device.modelName}
</Text>
</Text>
<Text style={styles.text}>
Constants executionEnvironment:{' '}
<Text style={styles.boldText}>{Constants.executionEnvironment}</Text>
</Text>
<Text style={styles.text}>
Environment: <Text style={styles.boldText}>{environment}</Text>
</Text>
<Text style={styles.text}>
Platform: <Text style={styles.boldText}>{deviceInfo.platform}</Text>
</Text>
{showDetails && (
<>
<Text style={styles.subtitle}>Quick Checks:</Text>
<Text style={styles.smallText}>
• iOS Simulator: {isSimulator ? '✅ Yes' : '❌ No'}
</Text>
<Text style={styles.smallText}>
• Expo Go App: {isExpoApp ? '✅ Yes' : '❌ No'}
</Text>
<Text style={styles.smallText}>
• Development Mode: {deviceInfo.isDevelopment ? '✅ Yes' : '❌ No'}
</Text>
{deviceInfo.deviceName !== undefined &&
deviceInfo.deviceName !== '' && (
<Text style={styles.smallText}>
• Device: {deviceInfo.deviceName}
</Text>
)}
{deviceInfo.osVersion !== undefined &&
deviceInfo.osVersion !== '' && (
<Text style={styles.smallText}>
• OS Version: {deviceInfo.osVersion}
</Text>
)}
</>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
margin: 8,
borderRadius: 8,
backgroundColor: '#f3f4f6',
padding: 16,
},
title: {
marginBottom: 8,
fontSize: 18,
fontWeight: 'bold',
},
text: {
marginBottom: 4,
fontSize: 16,
},
boldText: {
fontWeight: '600',
},
subtitle: {
marginTop: 8,
fontSize: 14,
fontWeight: '600',
},
smallText: {
fontSize: 14,
},
});
import type { ReactNode } from 'react';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { DeviceInfoDisplay } from './DeviceInfoDisplay';
import {
getDeviceInfo,
getEnvironmentDescription,
isExpoGoRunning,
isIOSSimulatorRunning,
isSimulatorOrEmulator,
logDeviceInfo,
} from './deviceDetection';
export default function DeviceTestScreen(): ReactNode {
// Get device information
const deviceInfo = getDeviceInfo();
const environment = getEnvironmentDescription();
const isSimulator = isIOSSimulatorRunning();
const isExpoApp = isExpoGoRunning();
const isSimulatorOrEmulatorRunning = isSimulatorOrEmulator();
// Log device info to console for debugging
React.useEffect(() => {
logDeviceInfo();
}, []);
return (
<View style={styles.container}>
<View style={styles.content}>
<Text style={styles.title}>Device Detection Test</Text>
<Text style={styles.description}>
This screen demonstrates how to detect if you're running in iOS
Simulator vs Expo Go app.
</Text>
{/* Show the device info display component */}
<DeviceInfoDisplay showDetails={true} />
{/* Show conditional content based on environment */}
<Text style={styles.sectionTitle}>Conditional Content:</Text>
{isSimulator && (
<Text style={styles.simulatorText}>
🎯 This content only shows in iOS Simulator
</Text>
)}
{isExpoApp && (
<Text style={styles.expoText}>
📱 This content only shows in Expo Go app
</Text>
)}
{isSimulatorOrEmulatorRunning && (
<Text style={styles.emulatorText}>
🖥️ This content shows in any simulator/emulator
</Text>
)}
{!isSimulatorOrEmulatorRunning && !isExpoApp && (
<Text style={styles.deviceText}>
📲 This content shows on physical devices
</Text>
)}
{/* Show raw device info */}
<Text style={styles.sectionTitle}>Raw Device Info:</Text>
<Text style={styles.rawInfo}>
{JSON.stringify(deviceInfo, null, 2)}
</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
padding: 16,
paddingTop: 50,
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 16,
},
description: {
marginBottom: 8,
marginTop: 16,
fontSize: 16,
lineHeight: 24,
},
sectionTitle: {
marginBottom: 8,
marginTop: 16,
fontSize: 16,
fontWeight: '600',
},
simulatorText: {
marginBottom: 8,
color: '#2563eb',
fontSize: 16,
},
expoText: {
marginBottom: 8,
color: '#16a34a',
fontSize: 16,
},
emulatorText: {
marginBottom: 8,
color: '#ea580c',
fontSize: 16,
},
deviceText: {
marginBottom: 8,
color: '#9333ea',
fontSize: 16,
},
rawInfo: {
borderRadius: 4,
backgroundColor: '#f3f4f6',
padding: 8,
fontSize: 12,
fontFamily: 'monospace',
},
});
{
"dependencies": {
"expo-constants": "~17.1.6",
"expo-device": "~7.1.4"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment