Les API des navigateurs natifs qui remplacent les packages npm populaires en 2026
Explique comment les fonctionnalités natives de JavaScript et CSS telles que Signals, l’opérateur pipeline, Temporal et le positionnement par ancre remplacent les packages npm courants.
Vaut la peine d’examiner un instant votre propre package.json : combien de ces entrées existent uniquement pour simuler une fonctionnalité que le navigateur a depuis appris à gérer de lui-même ?
Pendant la majeure partie des dix dernières années, la solution par défaut à presque tous les problèmes liés aux interfaces utilisateur était « utiliser un package ». Besoin de gestion d’état ? On recourt à Redux, Zustand ou MobX. Besoin de fonctions pour manipuler les dates ? Moment ou dayjs. Besoin d’outils utilitaires ? lodash. Besoin d’animations ? GSAP ou Framer Motion. Chaque framework a accumulé sa propre pile de code de liaison pour combler les lacunes de la plateforme.
D’ici 2026, ce schéma évolue plus rapidement que la plupart des équipes ne le réalisent. TC39 et les principaux fabricants de navigateurs ont passé ces dernières années à développer progressivement des équivalents natifs pour toute une série d’outils tiers. Voici cinq paquets que vous pouvez sérieusement envisager de supprimer de vos dépendances dès maintenant, ainsi que deux autres qui ne sont qu’à moitié obsolètes.
1. Bibliothèques de gestion d’état — les Signals natifs viennent d’arriver
Remplace : Redux, Zustand, MobX, Recoil, Jotai, ainsi que les mécanismes réactifs natifs des frameworks comme les références réactives de Vue
Remplacé par : les primitives standardisées Signal (State, Computed et l’aide à la souscription sub)
Peu de problèmes ont divisé le développement frontend autant que le choix d’une méthode pour gérer l’état. L’écosystème React a évolué avec Redux, puis Zustand, ensuite Jotai, et enfin Recoil. Vue a développé ses propres primitives réactives avant d’y ajouter Pinia par la suite. Solid et Svelte, quant à eux, ont été conçus dès le départ autour de signaux. Chaque framework a inventé sa propre version de la primitive réactive, ce qui signifiait que reutiliser la logique d’état entre frameworks était presque impossible.
Cette contrainte s’est atténuée en 2026 lorsque la proposition de signaux natifs du TC39 a été mise en œuvre. La primitive réactive existe désormais directement à l’intérieur du moteur JavaScript :
// No library. This runs in the browser as-is.
const counter = new Signal.State(0);
const doubled = new Signal.Computed(() => counter.get() * 2);
Signal.sub(() => {
console.log(`count: ${counter.get()}, doubled: ${doubled.get()}`);
});
counter.set(1); // triggers the subscription automatically
Voici ce que ce changement vous apporte réellement :
- Votre logique d’état peut être rédigée une seule fois et réutilisée partout — React, Vue, Solid et Svelte peuvent tous lire dans la même primitive de base
Certains ingénieurs présentent cela comme la fin d’un conflit qui durait depuis une décennie entre les frameworks frontend. Une fois le noyau réactif partagé entre les écosystèmes, les différences restantes entre les frameworks se réduisent à la syntaxe des templates et à la structure des composants — et non aux mécanismes de propagation des mises à jour d’état.
2. lodash — l’opérateur de pipeline met fin au « cousin du callback hell »
Remplace : lodash, ramda, ainsi que la plupart des utilisations de _.chain()
Remplacé par : l’opérateur de pipeline, |>
Il est probable que vous ayez déjà écrit quelque chose comme ceci :
const result = fn3(fn2(fn1(data)));
Ces appels de fonctions imbriquées — où il faut lire à l’envers pour comprendre l’ordre réel d’exécution — ont longtemps été l’un des principaux facteurs nuisant à la lisibilité du JavaScript. _.chain() de lodash servait autrefois à masquer ce problème, mais cela impliquait d’importer toute la bibliothèque rien que pour obtenir un ordre d’appel plus clair.
Début 2026, **l’opérateur de pipeline est passé au stade 4 dans ES2026**. La même expression se lit désormais naturellement de haut en bas :
const result = data
|> fn1
|> fn2
|> fn3;
Associé au support natif de await, les pipelines asynchrones se lisent presque comme des scripts shell :
const user = userId
|> fetchUser
|> await
|> extractProfile
|> await
|> formatOutput;
L’opérateur de pipeline permet de résoudre un problème de lisibilité, tandis que lodash s’occupait principalement du problème plus ancien consistant en l’absence totale d’outils fonctionnels dans le langage. Maintenant que le piping est intégré nativement, les méthodes de Array.prototype ont évolué, et structuredClone est disponible partout, la justification de l’existence de lodash s’est considérablement réduite. S’il figure encore dans vos dépendances en 2026, le supprimer représente probablement la façon la plus simple d’optimiser la taille de votre bundle.
3. dayjs et moment — L’API Temporal atteint 98 % de couverture des navigateurs
Remplace : moment.js, dayjs et date-fns pour la plupart des cas d’usage
Remplacé par : l’API Temporal
Cet élément est le moins controversé de la liste. moment.js fonctionne depuis des années en mode maintenance uniquement, et même le "léger" dayjs ajoute encore plus de 2 KB à votre bundle. Entre-temps, l’API Temporal a atteint 98 % de couverture des navigateurs.
// dayjs
const d = dayjs('2026-09-11').add(1, 'month').format('YYYY-MM-DD');
// Temporal
const d = Temporal.PlainDate.from('2026-09-11').add({ months: 1 }).toString();
Temporal ne se limite pas à une syntaxe plus propre — il élimine des bugs réels avec lesquels les bibliothèques de dates ont eu du mal pendant des années :
- Gestion des fuseaux horaires intégrée, il n’est donc pas nécessaire d’utiliser un plugin distinct
- Soutien aux systèmes de calendrier intégré, y compris les calendriers non grégoriens
- Les instances sont immuables, évitant le piège classique de moment.js consistant à modifier accidentellement un objet que l’on croyait inchangé
- La taille du bundle diminue de 10 à 50 KB
Pour les projets ciblant principalement un public mobile, cette réduction de 10 à 50 KB n’est pas seulement un avantage supplémentaire — elle se traduit directement par une meilleure note LCP.
4. Popper.js et Floating UI — Le positionnement par ancre est désormais un mécanisme natif de CSS
Remplace : Popper.js, Floating UI, Tippy.js
Remplacé par : Le positionnement par ancre en CSS
Si vous avez déjà créé une aide contextuelle, vous connaissez la procédure : il faut afficher un menu déroulant juste en dessous d’un bouton. L’approche traditionnelle consiste à utiliser position: absolute, à calculer manuellement les valeurs de top et left, puis à configurer des écouteurs pour les événements scroll et resize afin que l’élément ne s’éloigne pas de sa position. Sinon, on recourt à Popper.js ou Floating UI, ce qui ajoute encore une dizaine de kilooctets rien que pour gérer le positionnement.
D’ici 2026, le positionnement par ancre CSS gère cela au niveau de la plateforme :
/* Step 1: name the anchor element */
.button {
anchor-name: --my-trigger;
}
/* Step 2: pin the floating element to it */
.tooltip {
position: anchor(--my-trigger);
inset-area: bottom; /* below the anchor */
}
C’est tout — toute la solution. Aucun JavaScript, aucune calcul mathématique manuel pour le positionnement absolu, aucune bibliothèque externe. Imaginez le positionnement par ancre comme un verrou GPS pour les éléments UI flottants : pointez-le vers le bouton déclencheur, et il restera en place quel que soit le scroll de la page ou la modification de la taille de la zone visible.
5. Sass et PostCSS — encadrement natif, @layer et @scope
Remplace : Sass, Less, PostCSS et son écosystème de plugins
Remplacé par : l’encadrement natif CSS, @layer et @scope
Il a existé une époque où Sass et Less semblaient indispensables. Variables, encadrement, mixins, fonctions réutilisables — le CSS pur ne proposait tout simplement rien de tout cela. Ce n’est plus le cas en 2026.
Encadrement natif :
.card {
background: white;
& .title { font-weight: 600; }
&:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
}
@layer pour contrôler l’ordre de cascade :
@layer reset, base, components, utilities;
@scope pour une isolation légère des styles :
@scope (.card) to (.card__content) {
:scope { border-radius: 8px; }
}
OKLCH est devenu le format de couleur standard :
:root {
--color-primary: oklch(0.65 0.2 250);
--color-hover: oklch(from var(--color-primary) calc(l - 0.1) c h);
}
Avec les requêtes de conteneur, un alignement de texte précis grâce à text-box, une positionnement basé sur les éléments frères via sibling-index(), ainsi que des animations déclenchées par le scroll — tous fonctionnant de manière stable dans les navigateurs d’ici 2026 — Sass est passé d’une exigence obligatoire à un outil optionnel pour la plupart des projets. S’il fait toujours partie automatiquement de votre stack, il est utile de vérifier combien des fonctionnalités pour lesquelles vous l’utilisez peuvent désormais être gérées nativement.
Deux packages seulement partiellement remplacés
Tous les éléments de cette liste ne disposent pas encore d’un remplacement natif complet. Deux sont proches, mais la plateforme n’a pas encore entièrement rattrapé son retard.
Bibliothèques d’animation — GSAP et Framer Motion face aux transitions natives View Transitions. L’API View Transitions est devenue stable avec React 19.3, et son composant <ViewTransition> permet d’animer automatiquement les éléments lorsqu’ils entrent, sortent, se déplacent ou changent de taille. L’animation pilotée par le scroll, grâce à animation-timeline: scroll(), offre des indicateurs de progression, des effets parallaxe et des effets de fondus sans aucune utilisation de JavaScript. Néanmoins, pour des séquences d’animation complexes et chorégraphiées manuellement — du genre pour lequel GSAP est spécialisé — les outils natifs ne constituent pas encore un remplaçant complet.
Inference par IA — ONNX Runtime Web versus WebNN. Pour l’inference de modèles en navigateur, l’API WebNN peut accéder directement à l’accélération NPU au niveau du système, évitant ainsi la nécessité de charger des dizaines de mégaoctets de code d’exécution ONNX.
const context = await navigator.ml.createContext();
const builder = new MLGraphBuilder(context);
// build the inference graph...
const output = await context.compute(graph, inputs);
La limitation : WebNN ne dispose pas encore d’un support complet par les navigateurs, ce qui fait que ONNX Runtime Web reste pour l’instant le choix le plus fiable.
En supprimant ces cinq catégories d’une base de code frontend de taille moyenne, on peut réduire l’empreinte des dépendances de 100 à 300 KB. Sur une connexion mobile lente, cette réduction peut permettre d’économiser de 1 à 2 secondes pour le chargement initial de la page.
En résumé
JavaScript commence à ressembler véritablement à un langage de plateforme autonome. La compétence à développer n’est pas une expertise approfondie d’un framework ou d’une bibliothèque en particulier — c’est plutôt le jugement permettant de déterminer quand la plateforme suffit et quand une dépendance reste utile.
Alors jetez un coup d’œil à votre package.json : combien de lignes pourriez-vous supprimer aujourd’hui ?
Lectures complémentaires
- Comment résoudre les conditions de concurrence que le débouncing ne peut pas traiter dans les interfaces utilisateur de recherche — Découvrez pourquoi le débouncing seul ne peut pas empêcher que des réponses API obsolètes écrasent l’état de l’interface utilisateur, et explorez quatre solutions pratiques pour garantir l’ordre des requêtes.