Application React qui ne démarre pas ? 7 correctifs courants pour le serveur de dev
Quand une application React “ne démarre pas”, le symptôme est souvent l’un de ceux-ci :
npm start/yarn start/pnpm devreste bloqué (aucun serveur ne répond).- Le terminal affiche une erreur (port occupé, module introuvable, erreur de build).
- Le serveur démarre mais la page reste blanche (runtime error, bundle cassé).
- Le navigateur affiche
ERR_CONNECTION_REFUSEDou “This site can’t be reached”. - Vite / CRA / Next (mode dev) boucle sur des erreurs de dépendances.
Ce tutoriel propose 7 correctifs courants, avec diagnostic, explication, et commandes réelles. Il s’applique à la plupart des stacks React modernes : Create React App (CRA), Vite, Next.js (dev server), et des monorepos (pnpm workspaces, Yarn workspaces, Turborepo).
Avant tout : check-list de diagnostic (2 minutes)
Avant de “tout réinstaller”, récupérez des infos fiables :
-
Version de Node et du gestionnaire de paquets
node -v npm -v yarn -v pnpm -v -
Commandes de démarrage exactes
- CRA :
npm start/yarn start - Vite :
npm run dev/yarn dev/pnpm dev - Next :
npm run dev
- CRA :
-
Logs complets
- Relancez en mode verbeux si possible :
(Selon l’outil,npm run dev -- --debug--debugpeut ne pas exister ; l’idée est d’obtenir des logs plus détaillés.)
- Relancez en mode verbeux si possible :
-
Port et processus
- Quel port est censé être utilisé ? (3000, 5173, 8080…)
- Est-il déjà occupé ?
On passe maintenant aux correctifs.
Correctif 1 — Port occupé / serveur “démarre” mais rien ne répond
Symptômes typiques
- CRA : “Something is already running on port 3000”
- Vite : “Port 5173 is in use, trying another one…”
- Navigateur :
ERR_CONNECTION_REFUSEDsi le serveur a crashé, ou vous regardez le mauvais port.
Pourquoi ça arrive
Un autre processus écoute déjà sur le port (ancien serveur de dev, Docker, service local). Parfois, le serveur de dev choisit un autre port automatiquement, mais vous continuez à ouvrir l’ancien.
Diagnostic
macOS / Linux
lsof -i :3000
lsof -i :5173
Windows (PowerShell)
netstat -ano | findstr :3000
netstat -ano | findstr :5173
Résolution
-
Tuer le processus
- macOS / Linux :
kill -9 <PID> - Windows :
taskkill /PID <PID> /F
- macOS / Linux :
-
Changer de port
-
CRA (Create React App) :
PORT=3001 npm startSous Windows (PowerShell) :
$env:PORT=3001; npm start(Ou installez
cross-envpour un script portable.) -
Vite :
npm run dev -- --port 3001 -
Next.js :
npm run dev -- -p 3001
-
Point important
Si votre terminal indique “Local: http://localhost:5174/”, ouvrez ce port-là, pas celui que vous aviez en tête.
Correctif 2 — Mauvaise version de Node (ou incompatibilité OpenSSL)
Symptômes typiques
- Erreurs de type :
error:0308010C:digital envelope routines::unsupportedERR_OSSL_EVP_UNSUPPORTEDSyntaxError: Unexpected token '??'(features JS non supportées)- Vite/Next exige une version minimale.
Pourquoi ça arrive
Les outils front modernes s’appuient sur des versions récentes de Node. À l’inverse, certains projets anciens (CRA v4 par ex.) cassent avec Node trop récent (notamment Node 17+ et OpenSSL 3).
Diagnostic
node -v
cat package.json
Cherchez :
- un champ
enginesdanspackage.json - la doc du framework (Vite, Next) sur la version de Node supportée.
Résolution (recommandée) : gérer Node avec nvm / fnm
macOS/Linux avec nvm
nvm install 20
nvm use 20
node -v
Windows : nvm-windows ou fnm
Avec fnm (souvent plus simple) :
fnm install 20
fnm use 20
node -v
Cas particulier : CRA + OpenSSL
Si vous êtes bloqué sur une vieille stack et que vous devez utiliser Node 17/18+ :
export NODE_OPTIONS=--openssl-legacy-provider
npm start
Sous Windows (PowerShell) :
$env:NODE_OPTIONS="--openssl-legacy-provider"
npm start
Idéalement, préférez mettre à jour la stack (CRA → Vite, dépendances) plutôt que de garder ce contournement à long terme.
Correctif 3 — Dépendances cassées : node_modules corrompu, lockfile incohérent
Symptômes typiques
Cannot find module ...Module not found: Error: Can't resolve ...- Erreurs de résolution ESM/CJS (ex:
require is not defined,ERR_REQUIRE_ESM) - Le projet marchait hier, ne marche plus aujourd’hui après un
git pull.
Pourquoi ça arrive
Le dossier node_modules est un état local dépendant :
- de la version de Node
- du gestionnaire (npm/yarn/pnpm)
- du lockfile (
package-lock.json,yarn.lock,pnpm-lock.yaml) - de l’OS/architecture
Un lockfile modifié, un mélange de gestionnaires, ou une installation interrompue peut créer un état incohérent.
Résolution standard (propre)
-
Supprimer node_modules + caches de build
rm -rf node_modules rm -rf dist build .next .vite -
Supprimer le lockfile uniquement si nécessaire
- Si vous êtes sûr de vouloir régénérer :
rm -f package-lock.json yarn.lock pnpm-lock.yaml - Sinon, gardez le lockfile du projet et supprimez les autres (ne mélangez pas).
- Si vous êtes sûr de vouloir régénérer :
-
Réinstaller avec le bon gestionnaire
-
npm :
npm ci(
npm ciest plus strict et reproductible quenpm installsi vous avezpackage-lock.json.) -
yarn :
yarn install --frozen-lockfile -
pnpm :
pnpm install --frozen-lockfile
-
-
Relancer le serveur
npm run dev # ou npm start
Astuce : détecter un mélange de gestionnaires
Si vous voyez plusieurs lockfiles à la racine, c’est souvent un signal d’alerte. Un projet doit idéalement n’en avoir qu’un.
Correctif 4 — Erreurs ESM/CJS et “type: module” : import/export qui ne colle pas
Symptômes typiques
ReferenceError: require is not defined in ES module scopeError [ERR_REQUIRE_ESM]: require() of ES Module ... not supportedSyntaxError: Cannot use import statement outside a module
Pourquoi ça arrive
Node et l’écosystème JS ont deux systèmes de modules :
- CommonJS (CJS) :
require,module.exports - ES Modules (ESM) :
import,export
Le comportement dépend de :
package.json→"type": "module"(tout.jsest ESM)- extensions
.cjs/.mjs - configuration de bundler (Vite, Webpack) et de tooling (Jest, ESLint)
Une dépendance peut être ESM-only, ou votre config (ex: vite.config.js) peut être interprétée dans le mauvais mode.
Diagnostic
Regardez :
package.json:"type": "module"?- extensions de fichiers de config :
vite.config.jsvsvite.config.mjspostcss.config.jsvspostcss.config.cjstailwind.config.jsvstailwind.config.cjs
Résolutions fréquentes
A) Renommer les fichiers de config selon le mode
Si votre projet est ESM ("type": "module"), mais un outil attend du CJS :
- Renommez en
.cjs:postcss.config.cjstailwind.config.cjseslint.config.cjs(selon setup)
Exemple postcss.config.cjs :
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
B) Passer la config Vite en ESM explicite
vite.config.mjs :
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
C) Éviter les imports ambigus
Si une lib est ESM-only, assurez-vous que votre environnement de test/build le supporte (ex: Jest nécessite config spécifique ou migration vers Vitest).
Correctif 5 — Variables d’environnement manquantes (API URL, clés, mode)
Symptômes typiques
- Le serveur démarre, mais la page est blanche.
- Console navigateur :
Cannot read properties of undefinedsurprocess.env...ouimport.meta.env... - Erreurs réseau : appels vers
undefined/apiou vers la mauvaise URL.
Pourquoi ça arrive
Les variables d’environnement diffèrent selon l’outil :
- CRA :
process.env.REACT_APP_* - Vite :
import.meta.env.VITE_* - Next.js :
process.env.NEXT_PUBLIC_*côté client
Et elles sont souvent définies dans un fichier .env qui n’est pas commité (présent dans .gitignore). Après un clone, vous n’avez pas les bonnes valeurs.
Diagnostic
- Cherchez un exemple :
.env.example.env.local.example
- Cherchez dans le code :
REACT_APP_VITE_NEXT_PUBLIC_
Résolution
-
Créez le fichier d’environnement attendu :
- Vite :
cp .env.example .env - Next (souvent) :
cp .env.local.example .env.local
- Vite :
-
Remplissez les valeurs (exemple Vite) :
VITE_API_URL=http://localhost:8080 VITE_FEATURE_FLAG=true -
Redémarrez le serveur (important) Les variables sont lues au démarrage :
npm run dev
Piège classique : utiliser process.env dans Vite
Dans Vite, côté client, c’est import.meta.env. Si vous avez un code ancien CRA migré vers Vite, remplacez :
process.env.REACT_APP_API_URL→import.meta.env.VITE_API_URL
Correctif 6 — Problèmes de proxy/API : CORS, proxy CRA/Vite, backend non lancé
Symptômes typiques
- Le front démarre, mais toutes les requêtes API échouent :
CORS policy: No 'Access-Control-Allow-Origin'...net::ERR_CONNECTION_REFUSED404sur/api/...
- La page peut sembler “ne pas démarrer” car elle dépend de données initiales.
Pourquoi ça arrive
Le serveur React tourne (ex: localhost:5173), mais votre API n’est pas accessible (ex: localhost:8080 non lancé). Ou vous appelez l’API sans proxy et vous déclenchez CORS.
Diagnostic rapide
-
Vérifiez si l’API répond :
curl -i http://localhost:8080/health(Adaptez l’endpoint.)
-
Vérifiez l’onglet Network du navigateur : URL appelée ? code HTTP ?
Résolutions
A) Démarrer le backend
Souvent, la solution est simplement :
cd backend
npm run dev
B) Configurer un proxy (CRA)
Dans package.json (CRA) :
{
"proxy": "http://localhost:8080"
}
Puis redémarrez npm start.
C) Configurer un proxy (Vite)
Dans vite.config.js / vite.config.mjs :
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
},
}
Ensuite appelez l’API via /api/... depuis le front.
D) CORS côté backend (si vous ne voulez pas de proxy)
Activez CORS sur le serveur API (exemple Express) :
import cors from 'cors'
app.use(cors({ origin: 'http://localhost:5173' }))
Correctif 7 — Cache et watchers : HMR bloqué, “ENOSPC”, fichiers non détectés, antivirus
Symptômes typiques
- Le serveur démarre mais ne rebuild pas.
- Erreurs Linux :
ENOSPC: System limit for number of file watchers reached
- Sur Windows : lenteurs extrêmes, rebuild infini, antivirus qui scanne
node_modules. - En WSL/Docker : changements non vus.
Pourquoi ça arrive
Les dev servers utilisent des watchers (Chokidar, Watchpack) pour détecter les changements. Sur Linux, le nombre de watchers inotify peut être trop bas. Sur environnements virtualisés (WSL, Docker bind mounts), les événements de fichiers peuvent être perdus.
Résolution A — Augmenter la limite inotify (Linux)
cat /proc/sys/fs/inotify/max_user_watches
Augmenter temporairement :
sudo sysctl fs.inotify.max_user_watches=524288
Rendre permanent :
echo "fs.inotify.max_user_watches=524288" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Résolution B — Forcer le polling (WSL/Docker)
Vite (dans vite.config.*) :
export default {
server: {
watch: {
usePolling: true,
interval: 100,
},
},
}
CRA (variable d’env) :
CHOKIDAR_USEPOLLING=true npm start
Résolution C — Exclusions antivirus / indexation
Sur Windows/macOS, excluez le dossier du projet (ou au minimum node_modules) des scans temps réel. Cela peut transformer un démarrage de 2 minutes en 10 secondes.
Bonus : cas fréquents selon l’outil (CRA, Vite, Next)
Create React App (CRA) : “react-scripts not found”
- Vous avez peut-être installé les dépendances dans un autre dossier, ou
node_modulesest absent.
Commandes :
npm install
npm start
Si react-scripts est dans devDependencies, assurez-vous de ne pas être en mode production :
npm ci
Vite : plugin React manquant ou erreur de JSX
Vérifiez que vous avez bien :
npm i -D @vitejs/plugin-react
Et dans vite.config.* :
import react from '@vitejs/plugin-react'
Next.js : erreur “Module not found: Can’t resolve ‘react’”
Cela arrive si react/react-dom ne sont pas installés (ou versions incompatibles).
npm i react react-dom
npm run dev
Méthode “propre” de dépannage (si vous êtes bloqué)
Si malgré les 7 correctifs vous êtes encore bloqué, appliquez une stratégie systématique :
-
Partir d’un état propre
git status rm -rf node_modules dist build .next .vite npm ci # ou yarn/pnpm selon le projet -
Démarrer en isolant
- Lancez le serveur sans extensions navigateur.
- Désactivez temporairement les outils qui injectent du code (certains plugins).
-
Réduire l’espace de recherche
- Créez un projet minimal et comparez :
npm create vite@latest react-test -- --template react cd react-test npm install npm run dev
Si le projet minimal marche, le problème est spécifique à votre repo (config, dépendances, env).
- Créez un projet minimal et comparez :
-
Lire l’erreur à la première cause Souvent, la première erreur dans le log est la vraie cause ; les suivantes sont des conséquences.
Commandes “réflexes” utiles
-
Nettoyer et réinstaller (npm) :
rm -rf node_modules npm ci -
Vérifier les scripts disponibles :
cat package.json npm run -
Vérifier les versions installées :
npm ls react react-dom -
Trouver quel processus écoute sur un port :
lsof -i :5173 -
Tester une URL localement :
curl -I http://localhost:5173
Conclusion
Un serveur de dev React qui “ne démarre pas” n’est presque jamais un mystère : dans la majorité des cas, c’est un port occupé, une version de Node incompatible, des dépendances incohérentes, un conflit ESM/CJS, des variables d’environnement absentes, un proxy/API mal configuré, ou un souci de watchers/caches.
Si vous voulez, copiez-collez ici :
- le framework (CRA/Vite/Next),
- la commande lancée,
- les 20 premières lignes et les 20 dernières lignes du log,
- votre
node -vet le contenu des scriptspackage.json,
et je vous proposerai un diagnostic ciblé.