Développement 7 min de lecture

La crise d’identité de React : bibliothèque ou framework?

James Barnes Designer principal et développeur front-end

Demandez à un développeur React si React est un framework, et vous obtiendrez la réponse rituelle : « En fait, React est une bibliothèque. » Une bibliothèque pour construire des interfaces. Elle affiche des composants. Tout le reste, c’est votre problème.

Pendant des années, cette phrase a servi de carte « sortie de prison ». La gestion de l’état est lourde? Pas notre affaire, on est une bibliothèque. Aucune vraie solution pour les styles? Pas notre affaire. La performance s’effondre à moins de tout mémoïser à la main? Tenez, voici un autre hook. Chaque lacune de React est confiée à la communauté, puis la rustine de la communauté devient « la façon React ».

Pendant ce temps, React agit discrètement comme un framework. Sa propre documentation recommande maintenant de démarrer les nouveaux projets avec un framework comme Next.js. Il a mis Create React App à la retraite. Il livre un compilateur. Alors, c’est quoi? Une bibliothèque responsable de rien, ou une plateforme qui dicte comment construire? React veut l’autorité d’un framework avec la responsabilité d’une bibliothèque. Voilà la crise d’identité.

Svelte a fait le choix inverse. Il prend en charge toute l’expérience de développement, et ça se voit.

L’état : sous-traité dès le premier jour

React fournit useState pour l’état local et useContext pour transmettre des valeurs vers le bas. Dès que votre application a un état partagé qui change souvent, vous en découvrez les limites. Le contexte refait le rendu de tous ses consommateurs quand sa valeur change : c’est correct pour un thème, pénible pour un panier d’achat.

Alors la communauté a construit la pièce manquante. Puis l’a reconstruite. Redux, avec ses actions, ses réducteurs, ses répartiteurs et son code répétitif. Puis Redux Toolkit pour cacher ce code répétitif. Puis MobX, Recoil, Jotai, Zustand, Valtio, et ce qui sortira le mois prochain. Chacun est une solution à un problème que React a refusé de régler.

Ce n’est pas un écosystème florissant. C’est un symptôme. Quand chaque projet React sérieux doit choisir une bibliothèque d’état externe, la gestion de l’état n’est pas facultative. C’est une fonctionnalité manquante.

Les styles : React n’a jamais eu de plan

Le CSS a un vrai problème à grande échelle : tout est global. La réponse de React a toujours été, essentiellement, un haussement d’épaules. Vous avez une propriété className et un objet style en ligne, et bonne chance.

Impossible d’écrire les styles d’un composant dans le même fichier et de les limiter à ce composant. Alors la communauté est intervenue, encore. CSS Modules. Styled-components et Emotion, qui mettaient le CSS dans des chaînes JavaScript et en payaient le prix à l’exécution. Puis, quand les composants serveur ont rendu le CSS-in-JS à l’exécution plus compliqué, un grand virage vers Tailwind.

Tailwind n’est pas un projet React, et bien des gens l’aiment pour lui-même. Mais sa popularité dans l’univers React n’a rien d’un hasard. Quand votre framework n’offre aucun style encapsulé, entasser des classes utilitaires dans le balisage est le chemin le plus facile. Votre composant se retrouve avec un className plus long que sa logique, non pas parce que c’est du bon design, mais parce que React ne vous a jamais rien donné de mieux.

Le modèle de rendu et l’explosion des hooks

C’est la source de la plupart des maux de React. Quand l’état change, React réexécute toute la fonction de votre composant et, par défaut, tous les enfants en dessous. Il compare ensuite un DOM virtuel pour déterminer ce qui a vraiment changé.

Ce choix a des conséquences, et chaque conséquence a eu droit à son hook :

  • Recalculer des valeurs coûteuses à chaque rendu? useMemo.
  • Des fonctions recréées à chaque rendu qui cassent la mémoïsation des enfants? useCallback.
  • Des enfants qui refont leur rendu sans raison? React.memo.
  • Besoin d’une valeur qui survit aux rendus sans en provoquer? useRef.
  • Des effets de bord qui doivent s’exécuter après le rendu, avec un tableau de dépendances à garder parfaitement synchronisé à la main? useEffect, l’API la plus mal utilisée du front-end.
  • Puis useLayoutEffect, useReducer, useTransition, useDeferredValue, useSyncExternalStore, useOptimistic, useActionState…

Plusieurs d’entre eux n’existent pas pour ajouter des fonctionnalités, mais pour contourner le coût du rendu. Et la plus récente solution le prouve. React Compiler, arrivé en version 1.0 en octobre 2025, insère automatiquement la mémoïsation qu’on demandait aux développeurs d’écrire à la main depuis des années. C’est une prouesse d’ingénierie. C’est aussi une étape de compilation dont le rôle principal est de camoufler le modèle d’exécution.

Svelte prend ses responsabilités

Svelte dit ce qu’il est : un framework avec un compilateur. Et comme il contrôle toute la pile, il règle ces problèmes à la source au lieu de les sous-traiter.

Voici le même petit composant dans les deux. D’abord, React :

import { useState, useMemo } from 'react';
import styles from './Counter.module.css'; // fichier séparé pour les styles encapsulés

export function Counter() {
	const [count, setCount] = useState(0);
	const doubled = useMemo(() => count * 2, [count]);

	return (
		<button className={styles.button} onClick={() => setCount((c) => c + 1)}>
			{count} x 2 = {doubled}
		</button>
	);
}

Maintenant, Svelte 5 :

<script>
	let count = $state(0);
	let doubled = $derived(count * 2);
</script>

<button onclick={() => count++}>
	{count} x 2 = {doubled}
</button>

<style>
	button {
		padding: 0.5rem 1rem;
	} /* limité automatiquement à ce composant */
</style>

Les différences s’additionnent vite :

  • Une réactivité fine. Svelte ne réexécute pas votre composant. Quand count change, seules les parties du DOM qui en dépendent sont mises à jour. Pas de DOM virtuel, pas de tableau de dépendances, rien à mémoïser.
  • Un état qui passe à l’échelle. La même rune $state fonctionne dans un simple module .svelte.js, donc un état partagé n’est qu’un objet exporté. Pas de Redux, pas d’arbre de fournisseurs.
  • Du CSS encapsulé dans le même fichier. Écrivez du CSS normal dans un bloc <style> et il ne s’applique qu’à ce composant. Aucune bibliothèque de plus, aucune soupe de classes.
  • Tout est inclus. Transitions, animations, stores et liaison bidirectionnelle sont livrés avec le framework. SvelteKit est le framework d’application officiel pour le routage et le rendu serveur.

Svelte n’a rien de magique. Il a simplement décidé que l’expérience de développement est l’affaire du framework, pas de la communauté.

Pour être juste

React ne va nulle part, et il a de vraies forces. Son écosystème est énorme, le marché de l’emploi est vaste, React Native permet aux équipes de réutiliser leurs compétences sur mobile, et presque tous les problèmes qu’on rencontre ont déjà trouvé réponse quelque part. Son noyau minimal permet aussi aux grandes entreprises de bâtir exactement l’architecture qu’elles veulent.

Svelte a aussi connu ses remous. Le passage de la réactivité implicite des let de Svelte 4 aux runes de Svelte 5 a été une vraie migration pour les applications existantes. Et son écosystème, même s’il grandit, reste plus petit.

Mais rien de cela ne change le fond. Les lacunes de React ne sont pas des erreurs de jeunesse. Elles sont le résultat d’une décennie à répondre « ce n’est pas notre affaire ».

Choisir sa voie

Il n’y a rien de mal à être une petite bibliothèque. Il n’y a rien de mal à être un framework complet. Ce qui est frustrant, c’est d’être l’un ou l’autre selon ce qui arrange : un framework quand il s’agit de vous dire comment structurer votre application, une bibliothèque dès que quelqu’un demande pourquoi l’état, les styles et la performance sont encore le problème de quelqu’un d’autre.

Svelte a choisi sa voie. Il a pris en charge toute l’expérience de développement, et le résultat, c’est moins de code, moins d’outils et moins de débats sur laquelle des douze bibliothèques d’état installer. React aurait quelque chose à en apprendre. Honnêtement, avec un compilateur et un framework recommandé déjà en main, il a fait la moitié du chemin. Il lui reste à admettre ce qu’il est.

Sources

Continuer la lecture
enfr