Skip to content
OTFotf
All posts

Cursor rules that keep mobile repos shippable under production pressure

D
DaveAuthor
6 min read
Cursor rules that keep mobile repos shippable under production pressure

Every team using Cursor on a mobile repo hits the same moment. The agent scaffolds a screen beautifully, then imports a web-only library, breaks the Expo Router layout, or rewrites your auth guard with a pattern you banned three sprints ago. The fix is not a better prompt. It is rules checked into the repo that every agent run follows automatically.

This guide shows how to write Cursor rules that keep a React Native or Expo repo shippable: scoped rule files, mobile-specific constraints, and a review loop that catches drift. If you are standardizing conventions more broadly, our bulletproof .cursorrules walkthrough covers the file mechanics — here we go deep on mobile production concerns.

Why mobile repos need rules more than web repos

A Next.js mistake usually fails fast in the browser. A mobile mistake hides. A wrong import compiles, then crashes on a physical device. A navigation change works on one screen and breaks deep links everywhere — the exact class of bug our deep linking production checklist exists to prevent. A background task that polls too aggressively drains batteries and earns one-star reviews you cannot revert.

Mobile repos also mix more runtimes: TypeScript, native modules, Expo config plugins, EAS build profiles, and push notification services. An agent that does not know your boundaries will happily edit generated native folders, bump SDK versions casually, or add dependencies with native code that break Expo Go. Rules draw those boundaries in machine-readable form.

How Cursor rules work in practice

Cursor reads rule files from your repo — project rules in .cursor/rules/ and the legacy .cursorrules or .cursorrule files — and injects the relevant ones into the agent's context. Scoped rules apply when changed files match a glob pattern, so navigation rules load for route files and native-module rules load for plugin files. Always-on rules load every time, so reserve that lane for the five constraints that truly apply everywhere.

Keep the total rule surface small. Ten tight rules beat forty vague ones. The agent has finite context, and every paragraph of rules competes with your actual code. If a rule has not prevented a real mistake in the last month, delete it or fold it into a broader one.

One codebase. iOS, Android, and web.

The Fitness Kit ships with auth, a database, and a backend already connected — no setup. Live demo at fitness-preview.otf-kit.dev.

See the live demo

Structure rules for a mobile monorepo

A typical Expo repo benefits from four rule files. A root file states the stack and the hard never-dos. A routing file governs Expo Router conventions. A data file governs Supabase access and caching. A native file governs config plugins and EAS builds. Each file stays under 40 lines so agents actually absorb it.

---
description: Expo Router conventions for this repo
globs: app/**/*.tsx
---

# Routing rules

- Every route lives under `app/` and uses typed params via `useLocalSearchParams`.
- New screens must add a deep-link entry and be tested with the dev-client link.
- Never use `window.location` or web-only navigation APIs.
- Auth-gated routes wrap with `<RequireAuth>` from `components/auth`.
- Follow the guard pattern in `app/_layout.tsx`; do not invent new redirects.

The frontmatter scopes this file to route components only. An agent editing a Supabase helper never sees it, which keeps context lean and relevant.

Write constraints agents can actually follow

Vague rules produce vague compliance. "Write clean code" means nothing to an agent. "Use FlashList for lists over 20 items, keyed by stable id" is checkable, and it points at the performance practice in our FlashList production guide. Prefer rules with three properties: a trigger (when this applies), a directive (do this exact thing), and a pointer (the file or example that shows how).

---
description: Data layer conventions
globs: lib/**/*.ts, hooks/**/*.ts
---

# Data rules

- All Supabase queries go through helpers in `lib/supabase/`, never inline clients.
- Reads that back a list must use the offline-first cache in `lib/cache/` first.
- Mutations use optimistic updates with rollback; see `hooks/use-optimistic.ts`.
- Never select `*` on tables with media columns; list columns explicitly.
- Respect RLS: test new queries as the authenticated role, not service role.

Each bullet names a file. When the agent is unsure, it opens the pointer instead of improvising. That single habit eliminates most convention drift.

Lock down the native boundary

The highest-use rule in any Expo repo is the one that protects the native boundary. Agents love to fix build errors by touching android/ and ios/ directly, which silently forks you from managed workflow. State the boundary explicitly and give the approved alternative:

---
description: Native and build boundaries
globs: "**/*"
alwaysApply: true
---

# Native boundary

- Never edit `android/` or `ios/` directly. Use Expo config plugins in `plugins/`.
- Never bump `expo`, `react-native`, or SDK versions without human approval.
- New native dependencies must be validated against Expo Go or flagged for dev-client.
- EAS build profiles live in `eas.json`; mirror the plugin list from our config
  plugin setup before adding native deps.

This is an always-apply rule because the cost of one violation — a broken prebuild or a store rejection — dwarfs its context cost. Our Expo config plugins production guide is the canonical reference to link from this rule so agents learn the approved path.

Govern pushes, paywalls, and auth

Three mobile subsystems deserve their own rule coverage because agents misunderstand them most often. Push notifications need token registration, permission sequencing, and deep-link payload shapes. Paywalls need the RevenueCat entitlement checks from our paywalls guide rather than homegrown receipt validation. Auth needs the guard components and session refresh flow, never a new token store.

You do not need a full file for each. A compact always-apply block works:

- Push: register tokens via `lib/push/register.ts`; payloads must include `route` for deep links.
- Paywall: check entitlements via `lib/billing/use-entitlement.ts`; never validate receipts client-side.
- Auth: reuse `RequireAuth` and the session hook; never store tokens outside SecureStore.

Short, absolute, and pointing at code. Agents follow pointers far better than prose.

Review agent output like a senior would

Rules reduce mistakes; review catches the rest. Require agents to summarize what changed, which rules applied, and what they tested. For route changes, demand a deep-link test. For data changes, demand an offline test. For anything touching plugins or build config, demand a human sign-off before merge — no exceptions, since a bad native change can block the whole team until the next EAS build passes.

Add a weekly rules review to your routine. Pull the agent's most common correction from code reviews and promote it into a rule. Demote rules that never trigger. A repo whose rules track its real mistakes compounds in quality; a repo with frozen rules slowly turns them into decoration.

Roll out without breaking the team

Introduce rules incrementally. Week one: the native boundary and the data-layer file. Week two: routing and the push-paywall-auth block. Announce each addition in the PR that adds it, with an example of the mistake it prevents. Developers adopt rules they have seen save a build; they ignore rule dumps.

Measure the rollout by what stops happening: fewer reverted agent PRs, fewer deep-link regressions, fewer native-folder diffs, fewer review cycles per AI-assisted change. When those trend down across a month, your rules are earning their context tokens.

Sources

cursorreact-nativecross-platform
OTF Fitness Kit

Stop wiring. Start shipping.

  • Login, database, and backend already connected — nothing to set up
  • iOS + Android + web from one codebase
  • AI configs pre-tuned + 40+ tested prompts included