Depuis 2023 et sa sortie dans Symfony 6.3, le composant AssetMapper a progressivement changé le rapport du framework au JavaScript : au lieu d'imposer un bundler Node, il sert des modules natifs directement au navigateur. En 2026, la bascule est actée : les nouveaux projets webapp créés avec Symfony utilisent AssetMapper par défaut, la documentation le qualifie de prêt pour la production, et même le livre officiel The Fast Track, mis à jour pour Symfony 8.1, a remplacé Webpack Encore par AssetMapper dans son parcours front-end.
Ce guide pose les choses sans enthousiasme déplacé : ce que le navigateur sait faire aujourd'hui, ce qu'AssetMapper apporte réellement, où se situe Webpack Encore et comment décider pour un projet existant. Il s'adresse aux équipes Symfony qui veulent comprendre la nouvelle voie avant de s'y engager, et s'appuie sur les bonnes pratiques générales de nos guides Symfony 2026 pour l'ancrage dans le cycle de vie du projet.

Pourquoi Symfony a changé de stratégie front-end
Pendant dix ans, le front-end Symfony s'est organisé autour d'un principe : le navigateur ne comprend pas les modules tels quels, il faut donc bundler. Webpack Encore a excellentement rempli ce rôle, avec une API PHP qui masque la complexité de la configuration Webpack. Mais le terrain a bougé sous ses pieds : les navigateurs modernes supportent les modules ES natifs, la spécification des importmaps a stabilisé, et la majorité des applications Symfony n'ont jamais eu besoin de la puissance d'un bundler complet.
Le coût réel de la chaîne Node est souvent sous-estimé : installation et mises à jour de node_modules, vulnérabilités transitoires, temps de build en CI, dérive des versions entre environnements, barrière pour les profils back-end. Pour une application à rendu serveur avec du JavaScript d'appoint, ce coût n'achète plus grand-chose. Le pari d'AssetMapper est de le supprimer : servir les fichiers tels quels, laisser le navigateur résoudre les imports, et déléguer la gestion des versions à un mécanisme simple.
Il ne s'agit pas d'une mode. La même logique a déjà été validée ailleurs : les standards du web ont rattrapé les usages. À l'échelle du paysage JavaScript, où les frameworks et bundlers se succèdent vite, notre panorama des frameworks JavaScript 2026 montre que les écosystèmes matures convergent vers moins d'outillage imposé, pas plus.
AssetMapper : le fonctionnement sans build step
Le principe tient en trois briques. D'abord, les assets vivent dans un dossier dédié et sont servis en HTTP avec des en-têtes de cache corrects. Ensuite, un fichier importmap.json associe des identifiants logiques — ceux utilisés dans les instructions import — aux URLs versionnées des fichiers. Enfin, une commande de compilation parcourt les fichiers, calcule leur empreinte de version et produit la version optimisée pour la production.
Concrètement, écrire import { Controller } from '@hotwired/stimulus' dans un fichier servi par AssetMapper fonctionne : le navigateur lit l'importmap, télécharge le module correspondant, et résout ses propres dépendances. Plus de bundler pour assembler, plus de loader pour traduire, plus de configuration de résolution. Le dossier node_modules disparaît du projet, et avec lui la moitié de la surface d'attaque en dépendances.
Les dépendances JavaScript restent possibles : une commande du bundle dédié télécharge les packages souhaités depuis un registre de packages et les installe dans le dossier des assets en les épinglant dans l'importmap, avec un fichier de verrouillage des versions. L'équipe récupère les mises à jour quand elle le décide, pas quand un lockfile npm l'y oblige.
- Sans build step : pas de Node en développement, pas d'étape de compilation en CI, les fichiers servis sont les fichiers écrits.
- Versioning intégré : chaque asset porte une empreinte qui permet un cache long en production sans risque de servir une version périmée.
- Dépendances épinglées : les packages JavaScript sont enregistrés dans l'importmap avec des versions verrouillées, sans node_modules.
Stimulus et Turbo : l'interactivité à la sauce Symfony
AssetMapper ne dit rien de l'organisation du JavaScript : c'est le rôle de Symfony UX, qui continue de s'appuyer sur Stimulus pour les comportements et Turbo pour la navigation. Un contrôleur Stimulus relie un fragment HTML à une classe JavaScript via des attributs data ; Turbo remplace les navigations complètes par des échanges partiels de page, avec des frames et des streams pour les mises à jour ciblées.
Le bundle Stimulus, fourni par Symfony UX, est la liaison standard : il lit les contrôleurs du dossier assets, les enregistre auprès de l'application Stimulus et les connecte au DOM. Avec AssetMapper, rien à compiler : les contrôleurs sont des modules natifs, l'importmap les sert, et l'initialisation se fait dans un fichier d'entrée de quelques lignes.
Cette stack couvre un spectre large : validation de formulaires, composants dynamiques, infinite scroll, notifications en temps réel via des streams Turbo. Elle ne vise pas à remplacer une application front dédiée, mais à rendre les applications à rendu serveur nettement plus réactives sans quitter le paradigme du HTML généré côté serveur — exactement la philosophie derrière nos travaux sur les progressive web apps avec Symfony, où le serveur reste la source de vérité.

Webpack Encore : maintenu, mais devenu l'option legacy
Précision importante, car les rumeurs d'obsolescence vont vite : Webpack Encore n'est pas déprécié. La documentation officielle le décrit comme pleinement supporté, et pour les projets existants qui l'utilisent, il n'y a ni urgence ni risque immédié. Ce qui a changé, c'est son positionnement : pour un nouveau projet nécessitant un bundler, Symfony recommande désormais une alternative plus moderne, tandis qu'Encore reste la solution des bases existantes et des besoins spécifiques.
La frontière de décision est nette. Encore et les bundlers restent pertinents quand le projet exige une étape de transformation : TypeScript, JSX, Sass avancé, code splitting finement piloté, optimisation d'images dans la chaîne. AssetMapper gagne quand le JavaScript écrit est du JavaScript standard, que les styles sont du CSS, et que l'équipe veut supprimer la chaîne Node sans rien sacrifier.
| Besoin | AssetMapper | Webpack Encore / bundler |
|---|---|---|
| JavaScript standard, CSS | Natif, aucun build | Possible, mais overkill |
| TypeScript, JSX, Sass | Transpilation externe requise | Intégrée à la chaîne |
| Dépendances npm | Épinglées dans l'importmap | node_modules classique |
| Code splitting | Par modules natifs | Configuration fine |
| CI et onboarding | Aucune étape Node | Node requis partout |
| Position 2026 | Voie recommandée des nouveaux projets | Supporté, option legacy |
Migrer un projet existant depuis Encore
La migration est un chantier d'ingénierie, pas une réécriture. Les étapes se répartissent sur quelques jours pour une base saine. On commence par inventorier ce que la chaîne Encore transforme réellement : un projet qui n'utilise que du JavaScript standard et du CSS migre presque tel quel ; un projet qui compile du Sass ou assemble des polices doit traiter ces points un par un.
Le chemin type : installer le bundle AssetMapper, créer le fichier importmap, déplacer les entrées JavaScript depuis le dossier Encore vers le dossier assets, convertir les appels aux helpers Twig qui pointaient vers les entrypoints, puis supprimer la configuration Encore et les dépendances Node. Chaque étape est réversible tant que la chaîne ancienne n'est pas désinstallée, ce qui permet une migration par volets en production.
- Commencer par le périmètre simple : les pages dont le JavaScript est standard migrent d'abord, les volets complexes attendent leur plan.
- Garder les deux chaînes pendant la transition : Encore sert l'ancien, AssetMapper le nouveau, jusqu'au basculement complet.
- Tester le cache en production : la compilation d'assets versionne les fichiers, vérifiez les en-têtes de cache et le rechargement après déploiement.
Le point de vigilance principal concerne les chemins : les assets référencés en dur dans les templates — images, polices — doivent repasser par les helpers du framework pour bénéficier du versioning. C'est fastidieux mais mécanique, et c'est souvent l'occasion de repérer des assets morts.
Compiler et déployer les assets en production
Le mode développement sert les fichiers à la volée, avec l'importmap résolu à la demande. La production exige une étape de compilation unique : une commande du composant parcourt les assets, applique le versioning, minifie ce qui doit l'être et génère l'importmap définitif. Cette commande fait partie du build, au même titre que l'installation des dépendances PHP.
Dans une chaîne d'intégration continue, l'ordre des opérations compte : installer les dépendances, compiler les assets, exécuter les tests, construire l'image ou l'artefact de déploiement. Notre guide CI/CD Symfony détaille ces pipelines ; avec AssetMapper, l'étape Node disparaît du runner et le build gagne en rapidité et en reproductibilité, puisque le même environnement PHP produit l'application et ses assets.
Les en-têtes HTTP restent la responsabilité du serveur : cache long sur les assets versionnés, pas de cache sur l'importmap lui-même, qui change à chaque déploiement. Une configuration correcte se teste en une minute avec les outils de développement du navigateur : un rechargement après déploiement doit servir les nouvelles versions, pas les anciennes.

Les limites réelles d'AssetMapper
Honnêteté oblige : AssetMapper n'est pas la réponse à tout. La première limite est le TypeScript, qui exige une transpilation externe avant de rejoindre les assets ; les équipes fortement investies dans TS garderont un bundler. La deuxième concerne les applications front riches : dès qu'un routage client, un état global ou du JSX entre en jeu, la logique de build revient. La troisième est culturelle : les développeuses et développeurs habitués aux outils Node trouveront la gestion des dépendances par importmap différente, pas toujours plus simple selon les cas.
Il y a aussi un point de vigilance sur les performances : servir des centaines de petits modules non concaténés augmente le nombre de requêtes par rapport à un bundle unique. Les navigateurs modernes gèrent bien cette contrainte grâce au cache HTTP et au préchargement, mais elle se mesure sur les connexions lentes et les pages très chargées en JavaScript. La compilation de production adresse une partie du sujet ; le reste relève de la discipline d'écriture — peu de modules, bien choisis.
Enfin, la cohabition : dans un monorepo ou une équipe où plusieurs applications Symfony coexistent, certaines sous Encore, d'autres sous AssetMapper, la diversité des chaînes a un coût de maintenance. La décision se prend idéalement au niveau de l'organisation, pas projet par projet.
Feuille de route pour un projet Symfony en 2026
Pour un projet neuf, la décision est simple : Symfony 7.4 LTS, AssetMapper par défaut, Stimulus et Turbo via Symfony UX, compilation d'assets en CI. C'est la voie que le framework préconise, elle est documentée, éprouvée et alignée avec le cycle de support de la branche LTS — corrections jusqu'en novembre 2028, sécurité jusqu'en novembre 2029.
Pour un projet existant sous Encore sans friction particulière, la décision est tout aussi simple dans l'autre sens : ne migrez pas par principe. Encore est supporté, votre chaîne fonctionne, et la consolidation vaut plus que la nouveauté. Réservez la migration aux moments où la chaîne devient un problème mesuré : builds lents, vulnérabilités Node récurrentes, difficulté à onboarder.
Pour un projet existant qui souffre de sa chaîne front, cadrer le chantier comme toute migration : périmètre réduit d'abord, chaînes en parallèle pendant la transition, critères de sortie explicites. La question à se poser n'est pas « faut-il suivre la mode ? » mais « quel est le coût total de notre chaîne actuelle, et que gagne-t-on réellement à la simplifier ? ». Les projets qui répondent avec des mesures prennent de bonnes décisions dans les deux sens ; c'est la même discipline que nous appliquons à l'audit et à la migration des socles PHP et Symfony.