Imported from xleepy/books-app (
AGENTS.md). Install upstream withnpx skills add xleepy/books-app. Copyright stays with the author.
AGENTS.md — books-app (Frontend)
This file is for AI coding agents working on the books-app React Native / Expo frontend. It links all project guides and provides quick orientation.
Project Overview
React Native / Expo app for discovering, tracking, and discussing books. Uses Redux Toolkit + RTK Query for server state, React Navigation for routing, and MSW for mock API in development.
Stack: React Native 0.81, Expo 54, TypeScript 6.0, Redux Toolkit, RTK Query, React Navigation
Guides
| Guide | Purpose |
|---|---|
| Feature-Sided Design (FSD) Guide | Directory structure, layer boundaries (entities/, features/, widgets/, pages/, shared/), import rules |
| Redux & RTK Query Guide | Server state management, mutations with .unwrap(), cache invalidation, local slices vs RTK Query |
| React Patterns Guide | Component patterns from react.dev: data loading vs presentation, avoiding unnecessary effects, form state, waiting for data |
| Pencil Design Skill | Platform design patterns (M3/Glass UI), design token reference, MCP-tool workflow for editing .pen files |
Read the relevant guide before making changes to:
- Directory structure or imports → FSD Guide
- API layer, mutations, caching → Redux & RTK Guide
- Component design, effects, form state → React Patterns Guide
- Designing or updating designs in Pencil → Pencil Design Skill
Additional Reference Docs
The docs/ folder contains implementation specs and design references beyond the core guides:
| Document | Purpose |
|---|---|
| Implementation Plan | Phased milestones, screen inventory, tech stack, verification checklist |
| Challenges Spec | User-created challenges: API contract, UI spec, component breakdown |
| Design Proposal | Pencil design frames for all screens (code-native JSON) |
New Feature Workflow (SDD)
When a user asks for a new feature, follow Spec-Driven Development (SDD) — write the spec first, then implement:
- Create a spec doc at
docs/features/<feature-name>.md— define the API contract, types, UI/UX spec, component breakdown, and acceptance criteria before writing any code. Use the existing specs (friends, challenges) as templates. - Review the spec with the user — confirm the API contract, UI flow, and component breakdown look right.
- Implement from the spec — the spec doc becomes the source of truth for implementation.
- Update status — mark the spec as
in-progressduring implementation,completedwhen done.
Implementation Order
Always implement backend before frontend, and always generate the frontend API from the backend — never write manual injectEndpoints() calls on the frontend.
- Backend first — implement routes, services, schemas, mappers, and DB changes in
../books-app-backend/. - Export OpenAPI — the backend auto-generates the spec at
/docs/json. Export it withcd ../books-app-backend && npx tsx scripts/export-openapi.tsif the server isn't running. - Codegen the frontend API — run
npm run codegenin the frontend to producesrc/shared/api/*.generated.ts. This fetches the OpenAPI spec and generates typed RTK Query hooks with correct cache invalidation. - Never write manual API files — do NOT write
.injectEndpoints()calls manually insrc/shared/api/. The only exception issrc/shared/api/meApi.ts, which extends the generatedmeApi.generated.tswith routes that codegen cannot express. If a new API domain is needed, add it to the backend first.
Feature Documentation
Each major feature is documented in docs/features/<feature-name>.md. These files capture:
- Purpose — what the feature does and why
- Design decisions — approaches considered and the one chosen
- API contract — backend routes, request/response shapes
- UI/UX flow — screen navigation, user interactions, error states
- Notification behavior — push/in-app notifications triggered
- Status — draft / in-progress / completed
When a feature is completed, update its doc to reflect the final implementation and refine any earlier design notes that changed during development.
When updating any feature doc, revisit all other feature docs that reference it (by name, file path, API route, or shared component) and keep those cross-references accurate. This includes both frontend docs/features/*.md and backend ../books-app-backend/docs/features/*.md.
| Feature | Doc |
|---|---|
| Thread & Challenge Management | docs/features/thread-challenge-management.md |
| User-Created Challenges | docs/features/challenges.md |
Quick Commands
npm start # Expo dev server
npm run start:mock # Expo with MSW mocks (no backend needed)
npm test # Jest tests
npm run typecheck # TypeScript check
npm run lint # ESLint check
npm run codegen # Regenerate RTK Query APIs from backend OpenAPI
Architecture at a Glance
src/
├── app/ # Navigation, providers, root types
├── entities/ # Domain objects (Book, Thread, Review, etc.)
├── features/ # Self-contained features (auth, swipe-book, track-progress)
├── pages/ # Screen components (assemble widgets + features)
├── shared/ # UI primitives, API layer, theme, utilities
├── store/ # Redux store config + base API slice
└── widgets/ # Composite UI (ReadingCard, ReviewSection, etc.)
Design Workflow (Pencil)
We use Pencil for UI design drafts. The design file lives at:
docs/designs/design-proposal.pen
For platform patterns (Material 3, Glass UI), design token reference, and the MCP-tool workflow for creating and editing designs, see the Pencil Design Skill guide.
When to use Pencil
- New screens or flows — draft layout before writing code
- Design review — iterate visually with stakeholders
- Component anatomy — map reusable widgets from design to FSD layers
Design → Code Workflow
- Draft in Pencil first — follow the Pencil Design Skill guide for platform patterns (M3 vs Glass UI) and the MCP-tool workflow.
- Use variables — Reference design tokens like
$accent,$bg-primary,$font-primaryinstead of hardcoding hex values. This keeps designs consistent with the app's theme. - Generate code — Once the draft looks right, ask the agent to generate the React Native screen/component code from the design.
- Refine in code — Pencil drafts are approximations. Final polish (animations, dynamic data, exact spacing) happens in the actual component.
Pencil Conventions for This Project
- Frame naming — Use descriptive names:
heroCard,leaderSec,joinBtn - Screen frames — Each screen is a top-level frame with
width: 390(iPhone layout) - Icons — Use
lucideicon font (matches ourlucide-react-nativedependency) - Text sizing — Use
textGrowth: "fixed-width"for multi-line descriptions; default"auto"for single-line labels - Sizing — Prefer
fill_containerandfit_contentover hardcoded dimensions - Colors — Only use documented theme variables (see
src/shared/theme/index.ts)
Key Conventions
- Never edit generated files manually. Files in
src/shared/api/*.generated.ts,src/generated/prisma/, or any file with a.generated.suffix are produced by codegen tools. Always regenerate them via the appropriate command (npm run codegen,npm run db:generate, etc.). Manual edits will be lost on the next regeneration and can introduce type mismatches. - Never write manual API endpoints on the frontend. All RTK Query endpoints must come from codegen (backend → OpenAPI →
npm run codegen→.generated.ts). The only allowed exception issrc/shared/api/meApi.ts. If you need a new API route, implement it in the backend first, then regenerate. See Implementation Order. - Mutations must use
.unwrap()withtry/catchfor error handling - Separate data loading from presentation — Screen loads data, Form/Widget renders UI
- Don't use
useEffectto sync props → state — pass initial values as props, usekeyprop to reset - Wait for all data before rendering — show
ActivityIndicatorwhile any required query is loading - Import rules follow the FSD layer hierarchy; check the FSD Guide table
- Keep tests up-to-date — When you modify code that already has test coverage, check the existing tests first. Update or add tests to cover the new behaviour, and run
npm testto verify they pass. Never silently break existing tests. - Split page components into separate files — Complex screens should decompose into page-specific sub-components under
pages/{feature}/ui/components/. The screen file orchestrates data loading and composition; presentation components handle their own styles. See existing examples:pages/discussions/ui/components/,pages/settings/ui/components/. - Reset modal state without
useEffect— When a modal needs to reinitialize local state on open, wrap the inner content in a conditionally rendered nested component inside theModal. This preservesanimationTypewhile letting React mount/unmount the body naturally. See the React Patterns Guide for the full pattern. - When in doubt, ask the user — If you are uncertain about requirements, trade-offs, or the best approach to a problem, pause and ask the user before proceeding. Present the options or ambiguities you see, discuss possible solutions, and agree on a direction rather than making assumptions.
- Keep AGENTS.md up-to-date — If you modify code that changes any convention, stack version, directory structure, architecture, guide reference, feature doc table, Pencil frame listing, or quick command documented in AGENTS.md, update AGENTS.md to reflect the new reality. This file is the source of truth for future agents working on this codebase.
- Every screen must have an ErrorBoundary — Stack screens use
makeScreen()inRootNavigator.tsx; tab screens usewrapScreen()inTabNavigator.tsx. React Navigation swallows uncaught errors in its internal view hierarchy, so without per-screen boundaries a render crash produces a blank white screen. See the React Patterns Guide section 8 for details. - Chain
?.through every nullable level when accessing RTK Query data —data?.pagination?.total, notdata?.pagination.total. Thedatafield isundefinedbefore first fetch and can briefly beundefinedduring cache invalidation refetches. See the React Patterns Guide section 8 for the pattern.
Page Component Splitting Convention
When a screen grows beyond ~150 lines or contains multiple distinct UI sections, extract page-specific components into pages/{feature}/ui/components/.
Rules
- Screen file (
{Page}Screen.tsx) handles data loading, mutations, navigation, and composes sub-components - Component files are pure presentation: props in, UI out
- Each component owns its
StyleSheet— no shared styles across components - Components are not exported from
shared/orwidgets/— they are page-private
Example
pages/settings/ui/
SettingsScreen.tsx # data loading + composition
components/
SettingsHeader.tsx # header with back button + avatar
ProfileCard.tsx # user profile card
ToggleRow.tsx # reusable within this page
ChevronRow.tsx # reusable within this page
SignOutButton.tsx # sign out CTA
When Changing the Backend API
If you modify backend routes or response shapes:
- Ensure the backend server is running at
http://localhost:3000 - Run
npm run codegenin the frontend - The generated files will update automatically
- Run
npm run typecheckto verify frontend call sites
Related
- Backend project:
../books-app-backend/ - Backend guides: See
../books-app-backend/AGENTS.md