iOS and Android differ. Branch behavior with the Platform module, swap whole files with platform extensions, and even share code with the web via react-native-web.
Why: sometimes a value or a small behavior must differ per OS — padding for the status bar, a default font. Platform.OS is "ios" or "android"; Platform.select returns the matching branch. Keep these small and local; for big differences, use file extensions (next topic).
import { Platform, StyleSheet } from 'react-native'
const styles = StyleSheet.create({
header: {
paddingTop: Platform.OS === 'ios' ? 44 : 24,
...Platform.select({
ios: { fontFamily: 'Helvetica' },
android: { fontFamily: 'Roboto' },
}),
},
})Why: when an entire component differs per platform, give each its own file — Button.ios.tsx and Button.android.tsx. The bundler automatically picks the right one when you import "./Button", with no branching in your code. There is also a .native.tsx vs .web.tsx split for web.
components/
├── Button.ios.tsx ← used on iOS
├── Button.android.tsx ← used on Android
└── Button.web.tsx ← used on web (react-native-web)
import Button from './components/Button' // bundler picks the right fileWhy: occasionally you need more than the OS — the version, or whether you are in a tablet layout. Platform.Version gives the OS version; combine with Dimensions for responsive choices. Keep runtime branching readable by naming the condition.
import { Platform, Dimensions } from 'react-native'
const isOldAndroid = Platform.OS === 'android' && Number(Platform.Version) < 29
const isTablet = Dimensions.get('window').width >= 768
// use these named flags instead of inline checks scattered around