Use Cases (Diperbarui: 2/6/2026)

Claude Code dan React Native: Panduan Expo, Native, dan Release

Pakai Claude Code untuk React Native: Expo vs bare, permission, Metro, emulator, aksesibilitas, dan release checks.

Claude Code dan React Native: Panduan Expo, Native, dan Release

Tentukan batas mobile sebelum meminta kode

Claude Code berguna untuk React Native bukan hanya karena bisa membuat satu screen lebih cepat. Nilainya ada pada kemampuan membaca project, mengubah TypeScript, menjalankan command verifikasi, menjelaskan apakah native rebuild dibutuhkan, dan memberi handoff yang bisa diperiksa. Mobile punya batas lebih banyak daripada komponen web: permission iOS, package Android, resolusi Metro, development build, emulator, aksesibilitas, dan release checks.

Prompt yang lemah adalah “buatkan app React Native”. Prompt yang kuat menjelaskan apakah project ini Expo, perlu Expo development build, atau bare React Native dengan folder ios/ dan android/ yang dikelola tim. Prompt juga harus menyebut file yang boleh disentuh, command yang harus minta konfirmasi, dan platform yang wajib dites.

Rujukan resmi yang saya pakai adalah Claude Code overview, Claude Code permissions, Expo documentation, Expo development builds, React Native environment setup, React Native Native Modules, Metro troubleshooting, dan React Native accessibility. Kalau tim baru mulai, baca dulu Claude Code getting started guide lalu rapikan aturan lewat permissions guide.

Mulai dari project map

Project map adalah brief operasional pendek untuk agent. Harness berarti pijakan kerja agent: di mana Claude Code boleh bergerak, bagaimana hasil diverifikasi, dan aksi apa yang tidak boleh otomatis. Tanpa ini, Claude Code bisa membuat kode yang berjalan, tetapi melewatkan native rebuild, perbedaan iOS/Android, atau batas release.

flowchart LR
  A["Project map"] --> B["Claude Code task"]
  B --> C["JS/TS implementation"]
  B --> D["Native config"]
  C --> E["Metro and unit tests"]
  D --> F["Dev build / emulator"]
  E --> G["Accessibility check"]
  F --> G
  G --> H["Release checklist"]

Sebelum implementasi, simpan file kecil seperti ini:

# React Native task map

App type: Expo app using TypeScript and Expo Router.
Native runtime: Expo Go for pure JS changes, development build for native libraries.
Targets: Android emulator first, iOS simulator on macOS before release.
Allowed files: app/, components/, hooks/, app.config.ts, metro.config.js, __tests__/.
Do not change: package manager, app slug, bundle identifiers, signing files, .env files.
Verification: npm run lint, npm test, npx expo-doctor, Android emulator smoke test.
Handoff: list changed files, commands run, platform not tested, and any native rebuild needed.

Template Expo terbaru bisa membawa konteks untuk AI coding agents. Namun app lama sering berisi README usang, asumsi SDK lama, dan native settings yang tidak terdokumentasi. Minta Claude Code membaca repository asli sebelum mengubahnya.

Pilih Expo atau bare React Native dengan sadar

Dokumentasi React Native memisahkan alur framework dari setup langsung dengan Android Studio dan Xcode. Dalam praktik, Expo biasanya paling cepat untuk app baru. Bare React Native tetap masuk akal jika ada native SDK lama, Gradle kompleks, Pods custom, atau syarat vendor.

KeputusanExpo lebih cocokBare React Native lebih cocok
Kecepatan awalMVP, internal tools, belajar, fitur tercakup Expo SDKKode iOS/Android lama harus dipertahankan
Fitur nativeCamera, SecureStore, notification, config pluginsSDK custom, terminal pembayaran, Bluetooth khusus, build detail
Scope Claude Codeapp/, components/, app.config.ts, testsios/, android/, Codegen, Pods, Gradle, generated files
VerifikasiExpo Go atau development build, npx expo-doctornpm run android, pod install, Xcode/Android Studio

Jangan anggap Expo Go sebagai bukti release. Dokumentasi Expo menjelaskan Expo Go sebagai environment cepat dengan native libraries tetap. Jika library punya native code, gunakan development build dan minta Claude Code melaporkan bahwa binary baru dibutuhkan.

Untuk project Expo bersih:

npx create-expo-app@latest rn-claude-lab
cd rn-claude-lab
npx expo install expo-camera expo-secure-store @react-native-community/netinfo
npm install --save-dev @testing-library/react-native jest-expo @types/jest
npx expo start

Tekan a untuk Android Emulator atau i untuk iOS Simulator di macOS. Jika jaringan lokal memblokir device, npx expo start --tunnel bisa membantu, tetapi lebih lambat.

Sesuaikan permission Claude Code untuk mobile

Di React Native, satu command bisa membuat diff besar. expo prebuild, pod install, gradlew clean, dan eas build valid pada task yang tepat, tetapi tidak boleh berjalan diam-diam saat hanya mengubah UI kecil.

Claude Code permissions memisahkan allow, ask, dan deny. .claude/settings.json bersama bisa mengizinkan check aman, meminta konfirmasi sebelum native regeneration atau release build, dan memblokir secrets serta publishing commands.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(npm run lint)",
      "Bash(npx expo-doctor)",
      "Bash(adb devices)"
    ],
    "ask": [
      "Edit",
      "Bash(npx expo prebuild*)",
      "Bash(eas build*)",
      "Bash(cd ios && bundle exec pod install)"
    ],
    "deny": [
      "Read(.env)",
      "Read(.env.local)",
      "Bash(git push*)",
      "Bash(rm -rf*)"
    ]
  }
}

Ini bukan soal tidak percaya tool. Ini membuat efek samping mobile tetap bisa direview. Jika native rebuild memang perlu, Claude Code harus menjelaskan alasannya lebih dulu.

Buat screen dengan permission kamera

Use case pertama adalah QR scanner untuk check-in, inventory, atau internal tools. Expo Camera menyediakan CameraView dan useCameraPermissions. Minta Claude Code memisahkan tiga state: permission loading, permission belum diberikan, dan camera ready. Sertakan accessibility label dan proteksi agar scan tidak berulang.

// components/CameraQrCheck.tsx
import { CameraView, useCameraPermissions } from 'expo-camera';
import { useState } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';

type ScanResult = {
  data: string;
  type: string;
} | null;

export function CameraQrCheck() {
  const [permission, requestPermission] = useCameraPermissions();
  const [scan, setScan] = useState<ScanResult>(null);

  if (!permission) {
    return (
      <View style={styles.center}>
        <Text>Checking camera permission...</Text>
      </View>
    );
  }

  if (!permission.granted) {
    return (
      <View style={styles.center}>
        <Text style={styles.title}>Camera access is required</Text>
        <Text style={styles.body}>
          Allow camera access to scan QR codes on this device.
        </Text>
        <Pressable
          accessibilityRole="button"
          accessibilityLabel="Allow camera access"
          disabled={!permission.canAskAgain}
          onPress={requestPermission}
          style={({ pressed }) => [
            styles.button,
            pressed && styles.buttonPressed,
            !permission.canAskAgain && styles.buttonDisabled,
          ]}
        >
          <Text style={styles.buttonText}>Allow camera</Text>
        </Pressable>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <CameraView
        style={styles.camera}
        barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
        onBarcodeScanned={
          scan
            ? undefined
            : ({ data, type }) => {
                setScan({ data, type });
              }
        }
      />
      <View style={styles.result}>
        <Text accessibilityLiveRegion="polite" style={styles.title}>
          {scan ? `Scanned ${scan.type}` : 'Point the camera at a QR code'}
        </Text>
        {scan ? <Text selectable>{scan.data}</Text> : null}
        {scan ? (
          <Pressable
            accessibilityRole="button"
            accessibilityLabel="Scan another QR code"
            onPress={() => setScan(null)}
            style={styles.button}
          >
            <Text style={styles.buttonText}>Scan again</Text>
          </Pressable>
        ) : null}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#111827' },
  center: { flex: 1, justifyContent: 'center', gap: 12, padding: 24 },
  camera: { flex: 1 },
  result: { gap: 12, padding: 16, backgroundColor: '#f9fafb' },
  title: { fontSize: 18, fontWeight: '700', color: '#111827' },
  body: { fontSize: 15, lineHeight: 22, color: '#374151' },
  button: {
    alignItems: 'center',
    borderRadius: 8,
    backgroundColor: '#2563eb',
    paddingHorizontal: 16,
    paddingVertical: 12,
  },
  buttonPressed: { opacity: 0.75 },
  buttonDisabled: { backgroundColor: '#9ca3af' },
  buttonText: { color: '#ffffff', fontWeight: '700' },
});

Komponen ini bisa dipakai di project Expo setelah memasang expo-camera. Teks permission dan native config sebaiknya ada di app config karena beberapa perubahan butuh native rebuild.

// app.config.ts
import type { ConfigContext, ExpoConfig } from 'expo/config';

export default ({ config }: ConfigContext): ExpoConfig => ({
  ...config,
  name: config.name ?? 'rn-claude-lab',
  slug: config.slug ?? 'rn-claude-lab',
  ios: {
    ...config.ios,
    bundleIdentifier: 'com.example.rnclaudelab',
    infoPlist: {
      ...config.ios?.infoPlist,
      NSCameraUsageDescription: 'Scan QR codes for check-in.',
    },
  },
  android: {
    ...config.android,
    package: 'com.example.rnclaudelab',
    permissions: ['CAMERA'],
  },
  plugins: ['expo-camera'],
});

Expo config plugins menerapkan native settings saat prebuild dan native build. Instruksi penting untuk Claude Code: “jika mengubah app.config.ts, laporkan apakah development build diperlukan.”

Perlakukan error Metro sebagai bukti

Use case kedua adalah Unable to resolve module, terutama di monorepo. Troubleshooting resmi Metro menyebut reset cache, tetapi reset cache bukan analisis akar masalah.

Berikan Claude Code error penuh, command, package manager, layout workspace, dan file terakhir yang dipindah. Expo app di dalam workspace kadang perlu config ini:

// metro.config.js
const path = require('path');
const { getDefaultConfig } = require('expo/metro-config');

const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, '..');

const config = getDefaultConfig(projectRoot);

config.watchFolders = [workspaceRoot];
config.resolver.nodeModulesPaths = [
  path.resolve(projectRoot, 'node_modules'),
  path.resolve(workspaceRoot, 'node_modules'),
];

module.exports = config;

Jangan menambahkannya sembarangan. Expo app single-package biasanya tidak butuh. Minta Claude Code menjelaskan kenapa watchFolders diperlukan, dan jangan ubah Metro jika penyebabnya casing, dependency hilang, Babel config lama, atau import path salah.

Rencanakan native modules sebelum edit native code

Use case ketiga adalah menghubungkan vendor SDK atau API platform. Dokumentasi Native Modules sekarang berfokus pada Turbo Native Modules dan Codegen. Jadi task yang baik dimulai dari TypeScript interface, lalu masuk ke Android dan iOS.

Jika Camera, SecureStore, atau NetInfo dari Expo cukup, jangan membuat native module custom. Untuk terminal pembayaran, Bluetooth khusus, atau SDK auth internal, minta plan dulu.

Implement a native bridge plan, not the full code yet.

Goal: expose a device serial reader to TypeScript.
First output:
1. TypeScript interface and error model.
2. Android/iOS files that would need edits.
3. Build commands for each platform.
4. Risks: permissions, threading, simulator limitations, release signing.
Do not edit ios/ or android/ until the plan is reviewed.

Ini terasa lebih lambat di awal, tetapi membuat review lebih murah. Kotlin, Swift, Pods, dan Gradle perlu batas yang jelas.

Masukkan test dan aksesibilitas ke task yang sama

API aksesibilitas React Native memberi informasi ke VoiceOver dan TalkBack. Jika sebuah View harus accessible, label dan role adalah bagian dari implementasi.

Mulai dari unit test untuk state tanpa permission:

// __tests__/CameraQrCheck.test.tsx
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react-native';
import { CameraQrCheck } from '../components/CameraQrCheck';

const mockRequestPermission = jest.fn();

jest.mock('expo-camera', () => ({
  CameraView: 'CameraView',
  useCameraPermissions: () => [
    { granted: false, canAskAgain: true },
    mockRequestPermission,
  ],
}));

describe('CameraQrCheck', () => {
  beforeEach(() => {
    mockRequestPermission.mockClear();
  });

  it('requests camera permission from the empty state', () => {
    render(<CameraQrCheck />);

    fireEvent.press(screen.getByText('Allow camera'));

    expect(mockRequestPermission).toHaveBeenCalledTimes(1);
  });
});

Setelah itu cek di device atau emulator: permission dialog, jalur saat ditolak, rotasi, scan di cahaya rendah, dan screen-reader label. Handoff harus menyebut platform yang dites. “Android emulator passed, iOS not tested” berguna; “looks good” tidak.

Jadikan release check sebagai command

Dev Menu dan LogBox adalah tools development; release build berperilaku berbeda. Claude Code harus mengembalikan bukti command, bukan hanya bilang selesai.

npm run lint
npm test -- --runInBand
npx expo-doctor
npx expo start -c
adb devices
adb shell input keyevent 82
npx expo run:android
# macOS only:
npx expo run:ios

Jika memakai EAS Build, pisahkan development, preview, dan production. Jangan biarkan Claude Code mengubah bundle identifier, Android package, signing files, atau production profile kecuali task memang meminta.

Use case praktis dan kegagalan umum

Use case pertama adalah MVP Expo baru. Login, QR scan, secure local storage, API sederhana, dan workflow internal bisa dipisah menjadi screens, hooks, tests, dan config. Jika app punya target revenue, analytics dan CTA behavior harus masuk definition of done.

Use case kedua adalah memperbaiki bare React Native app lama. Metro error, crash hanya di Android, permission text iOS, dan native SDK upgrade cocok untuk Claude Code jika kamu meminta klasifikasi error, diff minimal, dan catatan native rebuild.

Use case ketiga adalah riset sebelum integrasi native SDK. Payment, health data, Bluetooth, dan enterprise auth perlu tabel supported OS, permissions, risiko store review, limit simulator, dan test devices. Gunakan juga review workflow checklist dan TDD guide.

Kegagalan yang sering muncul: Expo Go success bukan bukti release; reset cache bukan root cause; verifikasi iOS/Android tidak boleh ditunda; accessibility label bukan tempelan akhir; native build commands harus punya alasan. Ini masalah workflow, bukan masalah AI semata.

CTA: jadikan workflow mobile sebagai template

Di React Native, dampak terbesar datang dari project map, permission file, daftar command verifikasi, dan review checklist yang bisa dipakai ulang. Solo builder bisa mulai dari free cheatsheet. Kalau butuh prompt dan setup material siap pakai, lihat ClaudeCodeLab products. Tim yang ingin menerapkan aturan Expo/bare React Native, CI, release gates, dan training di repository nyata bisa memakai Claude Code training and consultation.

Baca juga Claude Code React development guide dan Flutter/Dart guide untuk perbandingan.

Setelah mencoba workflow ini, Masa menemukan tiga kebiasaan yang paling mengurangi rework: tentukan Expo vs bare sebelum implementasi, minta catatan development build setiap kali app.config.ts berubah, dan verifikasi permission serta Metro lebih dulu di Android Emulator. Untuk fitur native seperti Camera dan SecureStore, batas verifikasi lebih penting daripada kecepatan generate kode.

#Claude Code #React Native #mobile development #Expo #TypeScript
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.