All skills
neha avatar

/native-integration

@e775372

Review React Native native-module, permission, and background-task work. Use when integrating platform APIs, camera, biometrics, files, or reviewing a bridge or Turbo Module boundary.

  • 1 file
  • 4.3 KB
  • Updated 2 days ago
  • GitHub

Use this Skill: https://skilld.dev/gh/neha/rn-developer-skills/native-integration

This session only. Nothing lands on disk.

SKILL.md

≈51 tokens always: the name and description. ≈1k when used: this file.

Native Integration Skill

Applicability

  • Platforms: iOS and Android
  • React Native: 0.76+ (New Architecture interop assumed unless a checklist item says otherwise)

When to Use

  • Integrating a native module, Turbo Module, or platform API
  • Requesting permissions, or handling camera, biometrics, files, or location
  • Adding a background task or a native listener
  • Reviewing a change that crosses the JavaScript and native boundary

Severity

  • Merge-blocking: a permission prompt this diff adds loops after denial, or a listener this diff adds is not removed on unmount.
  • Should-fix: usage-string wording and when the prompt appears, as long as denial does not crash.

Guidance

Permissions

This skill owns when the prompt is shown and what denial looks like. Analytics consent is owned by security.

  • Permission is requested at the moment of use, not on app launch or screen mount
  • Denied, restricted, and revoked states have a path that does not crash or loop the prompt
  • The user can continue without the permission, or is told what is blocked and how to enable it in Settings
  • iOS usage strings explain the specific purpose; Android declares only the permissions the feature uses

Incorrect:

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

Correct:

async function onTakePhoto() {
  const status = await getCameraPermission();
  if (status === 'denied') {
    const next = await requestCameraPermission();
    if (next !== 'granted') {
      setNeedsSettings(true);
      return;
    }
  }
  if (status === 'blocked') {
    setNeedsSettings(true);
    return;
  }
  await openCamera();
}

Native boundary

  • The JavaScript API returns a result or a typed error; it does not throw an unstructured native exception into the screen
  • A missing or old native implementation has a fallback (hide the feature, or use a supported path)
  • Values crossing the bridge are serialisable; functions, class instances, and cyclic objects are not passed through
  • Platform differences are explicit (Platform.OS or separate files), not assumed to match
  • New Architecture interop is used when the app is on the New Architecture; the old bridge is not added for a new module without a reason

Lifecycle

  • Native listeners, sensors, and subscriptions are removed on unmount
  • Background work respects OS limits (time, network, and user-visible purpose) and can be cancelled
  • Work that must finish (upload, payment) is confirmed on the server, not only by a native callback
  • Native UI that presents a modal or activity restores the React Native screen when it dismisses

Anti-Patterns

Anti-Pattern Risk Fix
Requesting permission in useEffect on mount Prompt before the user understands why; denial with no recovery Request from the action that needs it, and handle denial
Treating "granted once" as permanent Revoked or limited permission crashes the next call Check status before every use
Passing a JS callback object into native and never removing it Leak and calls after unmount Subscribe with a cleanup function
Swallowing native errors as catch {} The screen looks idle while the feature failed Surface a typed error and a retry or fallback

Pitfalls

  • Android may deliver a permission result after the activity restarts. Do not assume the component that called request is still mounted.
  • iOS limited photo access is not the same as full access. Handle the limited set instead of treating it as denied or granted.
  • Biometric success proves the device unlocked a key; it does not by itself prove the server accepted the user. Confirm the session server-side.
  • A native module that touches UI or sensors must run on the platform's main thread. A background-thread call can crash or silently drop the event.
  • File URIs from the camera or picker are often temporary. Copy what you must keep, and do not log the path if it contains user content.

Source: SKILL.md on GitHub

No third-party reports yet.

Signed by skilld at e775372. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 2 days ago
version
1.1.0
platforms
[
  "ios",
  "android"
]
react-native-version
0.76+
Other metadata
tags
[
  "react-native",
  "native",
  "permissions",
  "turbo-modules"
]

README badge

README badge for neha/rn-developer-skills/native-integration