project-root/
β
βββ app/ # If you're using Expo Router (v2+)
β βββ _layout.tsx # Main layout (like stack navigation)
β βββ index.tsx # Home screen (default route)
β βββ auth/ # Auth-related screens
β β βββ login.tsx
β β βββ register.tsx
β βββ dashboard/
β β βββ index.tsx
β β βββ profile.tsx
β βββ (other routes...)
β
βββ src/ # If youβre not using Expo Router
β βββ screens/ # All main app screens
β β βββ HomeScreen.tsx
β β βββ LoginScreen.tsx
β β βββ ProfileScreen.tsx
β β βββ index.ts # Optional barrel export
β β
β βββ components/ # Reusable UI components
β β βββ Button.tsx
β β βββ InputField.tsx
β β βββ Header.tsx
β β βββ index.ts
β β
β βββ modals/ # All modal components
β β βββ CoinsPopup.tsx
β β βββ ConfirmDialog.tsx
β β βββ index.ts
β β
β βββ hooks/ # Custom React hooks
β β βββ useAuth.ts
β β βββ useFetch.ts
β β βββ useDebounce.ts
β β
β βββ context/ # React Context providers
β β βββ AuthContext.tsx
β β βββ ThemeContext.tsx
β β βββ index.ts
β β
β βββ utils/ # Helper functions and constants
β β βββ date.ts
β β βββ number.ts
β β βββ storage.ts
β β βββ index.ts
β β
β βββ types/ # TypeScript interfaces & types
β β βββ navigation.ts
β β βββ user.ts
β β βββ api.ts
β β βββ index.ts
β β
β βββ services/ # API calls or external services
β β βββ apiClient.ts
β β βββ authService.ts
β β βββ userService.ts
β β
β βββ config/ # App-wide configuration
β β βββ env.ts
β β βββ constants.ts
β β βββ theme.ts
β β
β βββ navigation/ # Navigation setup (if not using Expo Router)
β βββ AppNavigator.tsx
β βββ AuthNavigator.tsx
β
βββ assets/ # Static assets (images, fonts, icons)
β βββ fonts/
β βββ icons/
β βββ images/
β
βββ .env # Environment variables
βββ app.json # Expo configuration
βββ package.json
βββ tsconfig.json
βββ README.md
π§ Why This Structure Works
| Folder | Purpose |
| screens/ | Each screen in your app (Login, Home, etc.) |
| components/ | Small reusable UI pieces (Button, InputField, etc.) |
| modals/ | Isolated modal components (CoinsPopup, AlertModal, etc.) |
| hooks/ | Custom hooks (API fetching, form handling, etc.) |
| context/ | Global app context (AuthContext, ThemeContext) |
| utils/ | Helper and formatting functions |
| types/ | TypeScript interfaces & enums |
| services/ | API handling or third-party integrations |
| config/ | Environment, theme, and app-wide constants |
| navigation/ | Stack, Tab, or Drawer navigators (if not using Expo Router) |
π§ Why Expo Uses These Characters
| Symbol | Used For | Why |
_ | Layout or private route | Keeps layout files distinct from screens |
() | Route group | To group related routes without affecting URL |
[] | Dynamic parameter | To define variable route parts |
+ | Special routes | System-level routes like +not-found or +error |
π Folder/File Conventions Explained
| Example | Meaning |
_layout.tsx | /app/_layout.tsx | Defines a layout shared by all routes in the same folder (like a Stack, Tab, or Drawer). Every route inside that folder is wrapped with this layout. |
index.tsx | /app/index.tsx | The default route for that folder (like HomeScreen). When you navigate to /, this screen is shown. |
[id].tsx | /app/[id].tsx | A dynamic route β used for screens that depend on a variable parameter. Example: /users/[id] β /users/123 or /users/abc. You can access it via const { id } = useLocalSearchParams(). |
(group) | /app/(auth)/login.tsx | A route group β used to organize routes without affecting navigation paths. Useful for grouping related screens (like (auth), (tabs), (admin)), but the folder name doesnβt appear in the URL. |
+not-found.tsx | /app/+not-found.tsx | Shown automatically when a route isnβt found (like a 404 page). |
_layout.tsx inside (group) | /app/(tabs)/_layout.tsx | Defines a Tab or Stack layout specific to that group of routes. |
[...slug].tsx | /app/docs/[...slug].tsx | A catch-all route β matches multiple nested paths (e.g., /docs/getting-started/setup). |
[[...slug]].tsx | /app/docs/[[...slug]].tsx | An optional catch-all route β works with or without parameters. |
_sitemap.ts | /app/_sitemap.ts | Used to generate sitemap for web apps. Optional. |
Example Structure (Tabs + Auth + Dynamic)
app/
β
βββ _layout.tsx # Root layout (global stack)
β
βββ (auth)/ # Auth group (wonβt appear in URL)
β βββ _layout.tsx # Stack layout for auth flow
β βββ login.tsx
β βββ register.tsx
β
βββ (tabs)/ # Tabs group
β βββ _layout.tsx # Tab navigation layout
β βββ home.tsx
β βββ profile/
β β βββ index.tsx # Profile main screen
β β βββ [id].tsx # Dynamic user profile (e.g. /profile/123)
β βββ settings.tsx
β
βββ +not-found.tsx # 404 screen
π How this works:
/ β goes to (tabs)/home.tsx (main screen)
/profile β opens (tabs)/profile/index.tsx
/profile/123 β opens (tabs)/profile/[id].tsx
/login β opens (auth)/login.tsx
(auth) and (tabs) help you organize your routes but donβt appear in URLs.