Structure de projet Expo
Un squelette de démarrage pour une nouvelle app Expo — sans structure de dossiers encore définie.
À appliquer uniquement aux nouveaux projets. Si l'app possède déjà une mise en page, suivez ses conventions existantes et laissez les fichiers où ils sont — un point de départ par défaut, jamais un standard à imposer ou vers lequel migrer. En cas de doute sur le caractère nouveau du projet, demandez avant de déplacer quoi que ce soit.
L'ensemble de la mise en page, assemblée à partir des règles ci-dessous :
├── assets/
├── scripts/
├── src/
│ ├── app/ # Routes Expo Router UNIQUEMENT — chaque fichier est une route
│ │ ├── api/ # routes API serveur, regroupées ici
│ │ │ ├── user+api.ts
│ │ │ └── settings+api.ts
│ │ ├── _layout.tsx
│ │ ├── _layout.web.tsx # layout spécifique à la plateforme
│ │ ├── index.tsx
│ │ └── settings.tsx
│ ├── components/ # UI réutilisable : button, card, table…
│ │ ├── table/ # composant complexe → dossier + index.tsx
│ │ │ ├── cell.tsx
│ │ │ └── index.tsx
│ │ ├── bar-chart.tsx
│ │ ├── bar-chart.web.tsx # variante spécifique à la plateforme
│ │ └── button.tsx
│ ├── screens/ # corps d'écran que les fichiers route affichent
│ │ ├── home/
│ │ │ ├── card.tsx # utilisé uniquement par Home — non partagé
│ │ │ └── index.tsx # affiché par src/app/index.tsx
│ │ └── settings.tsx
│ ├── server/ # helpers serveur utilisés par app/api
│ │ ├── auth.ts
│ │ └── db.ts
│ ├── utils/ # helpers autonomes + tests colocalisés
│ │ ├── format-date.ts
│ │ └── format-date.test.ts
│ ├── hooks/ # hooks réutilisables : use-theme.ts…
│ ├── constants.ts
│ └── theme.ts
├── app.json
├── eas.json
└── package.json
src/ et src/app
Gardez le code de l'app sous src/ pour le séparer des fichiers de config. Expo Router supporte app/ et src/app/ nativement — pour basculer, déplacez le dossier et redémarrez le bundler. Le template par défaut utilise l'alias @/* vers ./src/* dans tsconfig.json.
src/app est routes uniquement : chaque fichier y devient une route, donc rien d'autre n'y a sa place. Tout le reste vit dans les dossiers frères.
components/ — UI réutilisable
UI générique et réutilisée (button, card, table) avec une seule export nommée chacune. Nommez les fichiers en kebab-case (bar-chart.tsx), en accord avec le template create-expo-app par défaut. Quand un composant grandit, donnez-lui son propre dossier avec la racine en index.tsx et colocalisez ses sous-composants privés à côté — le chemin d'import (@/components/table) reste inchangé.
screens/ — corps d'écran
Puisque les fichiers app/ doivent être des routes, l'UI d'écran complexe qui n'est pas réutilisée n'a pas de place là. Une fois qu'un écran devient assez gros pour nécessiter une scission en composants séparés, placez-le dans screens/ et laissez chaque route simplement afficher son écran :
import { Home } from "@/screens/home";
export default function HomeScreen() {
// préoccupations spécifiques à la route uniquement — p. ex. lire les params d'URL ici
return <Home />;
}
Colocalisez les composants privés d'un écran dans son dossier (screens/home/components/). Bonus : le même écran peut s'afficher sous plusieurs routes.
server/ + app/api/ — séparer le code serveur
Ajouter +api à un nom de fichier dans app/ en fait une route API serveur. Le code serveur diffère du code frontend — il s'exécute dans un environnement serveur type Node (déployé avec EAS Hosting ou sur des services tiers) et peut lire les vars env secrètes (process.env.X, pas seulement EXPO_PUBLIC_*). Gardez-le séparé :
- Regroupez toutes les routes sous
app/api/→/api/user,/api/settings. Cela les colocalise et évite les collisions (p. ex. un écran/useret une route/user). - Placez les helpers serveur partagés dans
src/server/. - Envisagez des règles ESLint qui isolent les fichiers
+apietserver/des vérifications frontend uniquement.
Code spécifique à la plateforme
Petites différences : utilisez Platform.select / Platform.OS. Pour les plus grandes, scindez en fichiers de plateforme au lieu de if/else en ligne — bar-chart.tsx + bar-chart.web.tsx, importés sans extension (@/components/bar-chart) ; Metro choisit le bon fichier par cible.
- Les props doivent être identiques entre variantes.
- Un fichier par défaut (sans extension de plateforme) est toujours obligatoire — rendez-le inactif si le composant est monoplatefrme.
- Extensions supportées :
.ios,.android,.native,.web.
Colocaliser styles et tests
- Styles : gardez l'objet
StyleSheet.create({ ... })au bas du fichier de composant plutôt que dans un fichier.stylesséparé. - Tests : placez
format-date.test.tsà côté deformat-date.ts(préféré à un dossier__tests__/séparé) pour que les fichiers testés soient évidents à première vue.
Fichiers IA et config
Les instructions d'agent vivent à la racine du repo — AGENTS.md / CLAUDE.md, avec les skills du projet sous .claude/. Les autres fichiers de config et assets restent en dehors de src/ : app.json / app.config.ts, eas.json, package.json, assets/, et scripts/.
Basé sur Expo app folder structure best practices par Kadi Kraman. Pour la priorité de src/ et la mécanique des alias, consultez la documentation Expo.