Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Rn Platform Specific

ASecurity

iOS / Android platform-specific code in React Native: Platform.OS, Platform.select, .ios.tsx / .android.tsx file extensions, native modules, permissions, safe area handling, status bar. Use this skill to: - Branch code at runtime via Platform.OS / Platform.select. - Use file extensions for whole-component swaps. - Link and use native modules (Expo SDK or autolinked bare). - Handle permissions across platforms. - Configure status bar and safe area correctly. Do NOT use this skill for: - Gene...

35 stars
0 votes
0 copies
0 views
Added 9/22/2026
developmentjavaswiftkotlinbashreacttestingapi

Works with

cliapi

Security Analysis

A96/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/22/2026

Install to Claude Code

$npx -y skills add AratKruglik/claude-sdlc --skill rn-platform-specific --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rn Platform Specific?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Rn Platform Specific
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aratkruglik-rn-platform-specific/badge)](https://www.skillsdirectory.com/skills/aratkruglik-rn-platform-specific)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: rn-platform-specific
description: |
  iOS / Android platform-specific code in React Native: Platform.OS, Platform.select, .ios.tsx / .android.tsx file extensions, native modules, permissions, safe area handling, status bar.

  Use this skill to:
  - Branch code at runtime via Platform.OS / Platform.select.
  - Use file extensions for whole-component swaps.
  - Link and use native modules (Expo SDK or autolinked bare).
  - Handle permissions across platforms.
  - Configure status bar and safe area correctly.

  Do NOT use this skill for:
  - General project structure (see rn-conventions).
  - Navigation (see rn-navigation).
  - Storage (see rn-state-and-storage).
  - Testing (see rn-testing).
user-invocable: false
paths: ["**/*.ios.*", "**/*.android.*", "ios/**", "android/**"]
---

# Platform-Specific Patterns

iOS and Android have real differences. RN abstracts most, but sometimes you need to branch.

## `Platform.OS`

```ts
import { Platform } from 'react-native';

console.log(Platform.OS);                  // 'ios' | 'android' | 'web' | 'windows' | 'macos'

if (Platform.OS === 'ios') {
  // iOS-only logic
}
```

`Platform.OS` is set at runtime by RN. Use for small branches:

```tsx
const elevation = Platform.OS === 'android' ? { elevation: 4 } : { shadowOpacity: 0.1 };
```

Don't fork entire components for 5 lines of difference — use `Platform.select` or inline conditionals.

## `Platform.select`

Declarative platform branching:

```ts
const styles = StyleSheet.create({
  card: {
    padding: 16,
    backgroundColor: '#fff',
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.1,
        shadowRadius: 4,
      },
      android: {
        elevation: 4,
      },
      default: {},   // web, windows, macos
    }),
  },
});
```

Each key returns a value; `Platform.select` picks the matching one.

## `Platform.Version`

Numeric on Android (API level: 28, 30, 33, 34), string on iOS (e.g. `'17.0'`):

```ts
if (Platform.OS === 'android' && Platform.Version >= 33) {
  // Android 13+ specific behavior
}

if (Platform.OS === 'ios' && parseInt(Platform.Version as string) >= 17) {
  // iOS 17+ specific
}
```

## File extensions

For whole-component swaps, Metro bundler picks files based on extension:

```
src/
├── components/
│   ├── DatePicker.tsx              # default for all platforms
│   ├── DatePicker.ios.tsx          # iOS-only override
│   ├── DatePicker.android.tsx      # Android-only override
│   ├── DatePicker.native.tsx       # native (iOS + Android, NOT web)
│   └── DatePicker.web.tsx          # web (RN Web)
```

```tsx
// import is the same — Metro resolves to the right file
import { DatePicker } from './components/DatePicker';
```

Use file extensions when:
- The two platforms need genuinely different markup.
- Native modules differ per platform.
- Otherwise, prefer `Platform.select` or inline conditionals — easier to read in one file.

## Native modules

### Expo SDK (managed)

Pre-installed, no native linking needed. Just install the JS package:

```bash
pnpm add expo-camera expo-location expo-notifications
```

```tsx
import * as Camera from 'expo-camera';
const [permission, requestPermission] = Camera.useCameraPermissions();
```

For custom native code in managed workflow, you need to migrate to dev-client or eject to bare.

### Bare RN (autolinking)

RN 0.60+ has autolinking — installing a package via npm/yarn/pnpm wires it up automatically:

```bash
pnpm add react-native-camera
cd ios && pod install                          # iOS only — install CocoaPods deps
```

After install:
- Run `npm run ios` / `npm run android` to rebuild with new native module.
- Restart Metro (`npm start --reset-cache` if cached).

Some packages need additional native config (manifest entries, Info.plist keys). Check package README.

### Custom native modules

Bare: write Objective-C/Swift (iOS) and Java/Kotlin (Android) modules. Beyond the scope of this skill.

Expo: write a config plugin that injects native code via the prebuild step. See `expo-build-properties` and `withDangerousMod` examples.

## Permissions

### Expo

Each feature-specific package handles its own permission flow:

```tsx
import * as Camera from 'expo-camera';
const [permission, requestPermission] = Camera.useCameraPermissions();
if (!permission?.granted) {
  await requestPermission();
}

import * as Location from 'expo-location';
const { status } = await Location.requestForegroundPermissionsAsync();
```

Declare permission descriptions in `app.json`:

```json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "Allow $(PRODUCT_NAME) to access your camera",
        "NSLocationWhenInUseUsageDescription": "Allow location access for map features"
      }
    },
    "android": {
      "permissions": ["CAMERA", "ACCESS_FINE_LOCATION"]
    }
  }
}
```

### Bare

Use `react-native-permissions` for unified API:

```tsx
import { check, request, RESULTS, PERMISSIONS } from 'react-native-permissions';

const status = await check(PERMISSIONS.IOS.CAMERA);
if (status !== RESULTS.GRANTED) {
  await request(PERMISSIONS.IOS.CAMERA);
}
```

Configure `Info.plist` (iOS) and `AndroidManifest.xml` (Android) with the right keys / permissions.

## Safe area

The notch (iPhone X+) and rounded corners (iPad/iPhone) eat into screen real estate. iOS has the home indicator; Android may have on-screen nav bar or gesture area.

### `react-native-safe-area-context` (preferred)

```tsx
// Wrap app once at root
import { SafeAreaProvider } from 'react-native-safe-area-context';

export default function App() {
  return (
    <SafeAreaProvider>
      <RootNavigator />
    </SafeAreaProvider>
  );
}

// Use SafeAreaView in screens
import { SafeAreaView } from 'react-native-safe-area-context';

<SafeAreaView style={{ flex: 1 }} edges={['top', 'bottom']}>
  {/* screen content */}
</SafeAreaView>

// Or insets for fine control
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
<View style={{ paddingTop: insets.top, paddingBottom: insets.bottom }}>...</View>
```

The RN-built-in `SafeAreaView` from `react-native` is deprecated — don't use it.

`edges` prop: which edges to apply safe area padding. Often `['top']` for screens with bottom tab nav (tab nav handles bottom safe area).

## Keyboard handling

```tsx
import { KeyboardAvoidingView, Platform } from 'react-native';

<KeyboardAvoidingView
  behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
  style={{ flex: 1 }}
  keyboardVerticalOffset={64}                  // header height
>
  {/* form */}
</KeyboardAvoidingView>
```

For more control, use `react-native-keyboard-controller`:

```tsx
import { KeyboardProvider } from 'react-native-keyboard-controller';
// Wrap app, provides better keyboard event APIs and animations.
```

## Status bar

### Expo

```tsx
import { StatusBar } from 'expo-status-bar';
<StatusBar style="auto" />
```

`style`: `'auto'` (matches color scheme), `'light'`, `'dark'`, `'inverted'`.

### Bare

```tsx
import { StatusBar } from 'react-native';
<StatusBar barStyle="dark-content" backgroundColor="#fff" translucent={false} />
```

`backgroundColor` is Android-only; iOS uses the underlying view's color.

## Pixel ratio and dimensions

```tsx
import { Dimensions, useWindowDimensions, PixelRatio } from 'react-native';

// One-time read (doesn't update on rotation)
const { width, height } = Dimensions.get('window');

// Reactive — updates on rotation/resize
const { width, height } = useWindowDimensions();

// For native conversions (rare)
const px = PixelRatio.getPixelSizeForLayoutSize(50);
```

Use `useWindowDimensions` for layouts that adapt to orientation.

## Common platform pitfalls

| Issue | Platforms | Fix |
|---|---|---|
| Shadows differ | iOS uses `shadowColor/Offset/Opacity`; Android uses `elevation` | `Platform.select` |
| Status bar overlaps content | iOS by default doesn't; Android `translucent` does | Set `translucent={false}` or wrap in SafeAreaView |
| Back button | Android has hardware back; iOS doesn't | `BackHandler` (Android) for custom logic; React Navigation handles automatically |
| Date/time picker | iOS shows wheel; Android shows native dialog | `@react-native-community/datetimepicker` handles both |
| Keyboard appearance | iOS animates over content; Android may resize layout | `KeyboardAvoidingView` with `behavior` per platform |
| Linking external apps | iOS has stricter URL scheme rules | `Linking.canOpenURL` before `openURL`; declare allowed schemes in `LSApplicationQueriesSchemes` (iOS) |
| Push notifications | Different APNs (iOS) vs FCM (Android) tokens | Use `expo-notifications` or `react-native-firebase` for unified API |
| Notch / Dynamic Island (iOS) | Only iOS | SafeAreaView handles automatically |

## Anti-patterns

- ❌ Forking entire screens for `Platform.OS === 'ios'` when 90% of code is shared — use inline conditionals or `.ios.tsx`/`.android.tsx` only for genuinely different markup.
- ❌ Ignoring safe areas — content clipped by notch/home indicator.
- ❌ Calling `NativeModules.X` directly without Platform check — module may not exist on the other platform = crash.
- ❌ Using web-only positioning (`position: 'fixed'`).
- ❌ Hardcoding pixel values without considering pixel ratio (use density-independent units; RN's "px" already handles this).
- ❌ Forgetting to declare permission usage strings in `app.json` / `Info.plist` — App Store / Play Store rejection.
- ❌ Assuming Android back button works without handling — `BackHandler.addEventListener('hardwareBackPress', ...)`.
- ❌ Mixing the deprecated `SafeAreaView` from `react-native` with `react-native-safe-area-context`.

Attribution

AratKruglikAratKruglik
View sourceMore from AratKruglik →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284722 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2192 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →