expo-project-structure

Par expo · skills

Framework (OSS). Structure de dossiers pour une nouvelle application Expo. À utiliser lors de la création ou de l'organisation d'un nouveau projet Expo avec Expo Router, ou pour déterminer où placer un fichier. Pour les nouveaux projets uniquement — ne jamais restructurer une application existante pour l'y conformer.

npx skills add https://github.com/expo/skills --skill expo-project-structure

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 /user et une route /user).
  • Placez les helpers serveur partagés dans src/server/.
  • Envisagez des règles ESLint qui isolent les fichiers +api et server/ 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 .styles séparé.
  • Tests : placez format-date.test.ts à côté de format-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.

Skills similaires