avatar
Published on

Configuring Claude Code Permissions for React Native Development

Authors
  • avatar
    Name
    Mick MacCallum
    Twitter
    @0x7fs

React Native development involves a lot of shell commands. You're running Metro, installing pods, building to simulators, clearing caches, and occasionally nuking your node_modules when things get weird. If you're using Claude Code to help with this, you'll quickly get tired of approving the same safe commands over and over.

Claude Code has a permission system that lets you pre-approve commands matching certain patterns. Configuring this well makes the difference between a smooth workflow and constant interruptions.

Understanding the Permission Modes

Claude Code ships with three built-in permission modes. The default mode requires approval for most operations, which is sensible for general use but friction-heavy for React Native work where you might run dozens of build commands in a session.

You can check your current mode with:

claude config get --global defaultPermissionMode

The options are default, allowEdits, and plan. For most developers, default or allowEdits combined with custom allow rules works best. Switching to a fully permissive mode isn't necessary when you can just approve the specific commands you actually use.

Setting Up Allow Rules

The real power is in the allow rules. These live in your settings file at ~/.claude/settings.json and let you pre-approve commands matching glob patterns.

Here's a configuration that covers most React Native workflows:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(npm install*)",
      "Bash(npm ci)",
      "Bash(npx expo *)",
      "Bash(npx react-native *)",
      "Bash(yarn *)",
      "Bash(pod install*)",
      "Bash(bundle exec pod install*)",
      "Bash(xcodebuild *)",
      "Bash(adb *)",
      "Bash(watchman watch-del-all)",
      "Bash(rm -rf node_modules)",
      "Bash(rm -rf ios/Pods)",
      "Bash(rm -rf ios/build)",
      "Bash(rm -rf android/build)",
      "Bash(rm -rf android/app/build)"
    ]
  }
}

A few things to note about this configuration. The patterns use glob syntax, so npm run * matches npm run ios, npm run android, npm run start, and any other npm script. The npx expo * and npx react-native * patterns cover the CLI commands you'll use constantly.

The deletion patterns are intentionally specific. Rather than allowing rm -rf * (which would be dangerous), each pattern targets a specific directory that's safe to delete and regenerate. This is the kind of nuance that matters—you want convenience without giving up safety for destructive operations.

Project-Level Overrides

Sometimes you need project-specific rules. Maybe one project uses pnpm instead of npm, or has custom scripts with unusual names. You can add a .claude/settings.json in your project root:

{
  "permissions": {
    "allow": [
      "Bash(pnpm *)",
      "Bash(./scripts/*.sh)"
    ]
  }
}

Project settings merge with your global settings, so you don't need to repeat everything. Just add what's specific to that project.

Commands Worth Keeping Gated

Not everything should be auto-approved. I'd recommend keeping these behind the approval prompt:

Git operations that push or modify history are worth a pause. Commands like git push, git reset --hard, or git rebase can cause real damage if executed at the wrong time. The few seconds to approve them is cheap insurance.

Environment modifications like changes to your .zshrc, .bashrc, or global npm config can have unexpected consequences. Same with anything that modifies system paths.

Publishing operations including npm publish, expo publish, or fastlane release should always require explicit approval. You don't want to accidentally ship something.

The CLAUDE.md Approach

Beyond permissions, you can guide Claude Code's behavior with a CLAUDE.md file in your project root. This isn't about permissions but about context. For a React Native project, something like this helps:

# Project Setup

This is a React Native project using Expo (bare workflow).

## Common Commands
- `npm run ios` - Run on iOS simulator
- `npm run android` - Run on Android emulator
- `npm run start` - Start Metro bundler

## Build Issues
If iOS build fails, try:
1. `rm -rf ios/Pods && pod install --project-directory=ios`
2. Clean build folder in Xcode (Cmd+Shift+K)

If Android build fails, try:
1. `cd android && ./gradlew clean && cd ..`

This gives Claude Code the context to suggest the right commands without you having to explain your project structure every time.

Validating Your Setup

After configuring permissions, test that everything works as expected:

claude "run the ios app"

If your allow rules are set up correctly, Claude Code should execute npm run ios (or your equivalent) without prompting. If it still asks for approval, check that your pattern matches exactly—a missing asterisk or typo in the path will cause the rule to not apply.

You can see which rules are active with:

claude config get permissions

This shows both global and project-level rules, which helps when debugging why something isn't being auto-approved.

Finding the Right Balance

The goal isn't to approve everything automatically. It's to remove friction from the commands you run constantly while keeping guardrails around operations that could cause problems. For React Native specifically, that means being generous with build and run commands, cautious with anything that modifies git history or publishes artifacts, and thoughtful about deletion patterns.

Start with the configuration above and adjust based on what you find yourself approving repeatedly. If you're clicking "approve" on the same command multiple times a day, add it to your allow list. If you're nervous about a pattern being too broad, keep it gated.

For more details on Claude Code's permission system, see the official documentation.