mobile-frontend
Installation
SKILL.md
Mobile Frontend Skill
When to Use
- Building or editing
apps/mobilescreens, components, hooks, or providers - Working with Expo Router navigation or mobile interaction flows
- Reusing
@repo/uinative components and NativeWind styling
Scope
This skill covers mobile UI composition and app-side interaction patterns.
- Use
backendfor server work. - Use
mobile-recording-assistantfor deep recorder-specific service changes. - Use
react-native-reusables-expertfor primitive/component-library work.
Rules
- Style every
Textexplicitly; React Native does not inherit text styling. - Prefer semantic tokens such as
text-foregroundandbg-background. - Reuse shared providers and service instances instead of creating parallel state.
- Subscribe to specific events and clean subscriptions up.
- Use navigation/store patterns already established in the app for complex payload handoff.
- Do not import database clients directly into mobile UI.
Default Patterns
function RecordMetrics() {
const service = useSharedActivityRecorder();
const readings = useCurrentReadings(service);
return (
<View className="bg-card p-4">
<Text className="text-foreground text-lg font-semibold">
{readings.heartRate ? `${readings.heartRate} bpm` : "--"}
</Text>
</View>
);
}
Repo-Specific Guidance
- Recorder state should flow through shared provider/hook patterns.
apps/mobileuses Expo Router, NativeWind, Zustand, and shared@repo/uiprimitives.- For React Hook Form + Zod screens, prefer
useZodFormanduseZodFormSubmitfrom@repo/ui/hooksplus shared wrappers from@repo/ui/components/formbefore writing ad hocControllerrender blocks. - Prefer
FormTextField,FormTextareaField,FormSwitchField,FormSelectField,FormDateInputField,FormWeightInputField,FormBoundedNumberField, andFormIntegerStepperFieldwhen the screen is binding a standard shared field shape. - Fall back to raw
FormFieldonly when a widget is truly custom, multi-control, or does not match the existing shared wrapper contracts. - Prefer targeted hooks over broad service subscriptions.
- Keep runtime device or service behavior visible in UI state rather than hidden side effects.
Shared Form Guidance
const form = useZodForm({
schema: profileSchema,
defaultValues: { username: "", is_public: false },
});
return (
<Form {...form}>
<FormTextField control={form.control} label="Username" name="username" />
<FormSwitchField control={form.control} label="Public Account" name="is_public" />
</Form>
);
- Keep schema ownership in
@repo/coreand form interaction ownership in@repo/ui. - Prefer wrappers for repeated mobile form fields so labels, messages, accessibility, and parsing stay consistent.
Avoid
- Unstyled
Text - Duplicate service instances
- Catch-all subscriptions that trigger broad re-renders
- Direct Supabase or database usage in mobile components
Quick Checklist
- text styled explicitly
- shared providers/hooks reused
- subscriptions cleaned up
- navigation pattern matches existing app flow
- UI uses semantic tokens and shared components