WebAssembly a beaucoup appris depuis 2017. Il sait travailler avec des mémoires partagées, SIMD, les exceptions, les tail calls, la mémoire 64 bits et désormais le garbage collection.1 Cette liste change complètement les langages capables de cibler Wasm sans perdre en route leurs abstractions habituelles.
Ouvrez maintenant le navigateur et essayez d’écrire console.log("bonjour").
Là, le progrès des neuf dernières années devient presque comique. WebAssembly ne peut toujours pas saisir directement console, lui passer sa chaîne et continuer sa vie. Il lui faut un pont côté JavaScript, avec une fonction importée, une lecture de la mémoire Wasm, un décodage de la chaîne en objet JavaScript et enfin l’appel à l’API Web.1
Mozilla parle d’un statut de langage de seconde classe sur le Web. La vitesse ou la richesse de Wasm n’est plus le cœur du problème : JavaScript garde deux privilèges que le navigateur ne donne pas directement à Wasm, charger naturellement un programme et accéder aux Web APIs.1
Ce sont deux détails d’intégration. Ils suffisent à transformer un format conçu pour le Web en invité dans son propre navigateur.
Deux privilèges
Pour charger du JavaScript, une page peut utiliser un script ou un import. Le navigateur sait récupérer le fichier, le placer dans son graphe de modules, résoudre ses dépendances et l’exécuter.
Le chemin Wasm stable reste beaucoup plus impératif : récupérer le binaire, préparer les imports, appeler WebAssembly.instantiateStreaming() ou une API voisine, et enfin récupérer l’instance avec ses exports.17
Ce premier écart est enfin en train de bouger. La proposition ES Module Integration est en phase 3 du processus WebAssembly et définit aussi bien l’import d’un module Wasm depuis JavaScript que son chargement via un <script type="module">.23
Mozilla a implémenté en 2026 la première moitié de ce chemin dans Firefox : les source phase imports, qui permettent de récupérer un WebAssembly.Module dans le système ESM.5 Mais le ticket consacré à la phase suivante, celle qui lie et instancie directement le module, reste séparé.6
La nuance est importante : voir des commits « Wasm ESM » ne signifie pas qu’une page web peut déjà traiter partout un .wasm exactement comme un .js exécutable.
Et même quand ce chargement sera banal, il restera le plus gros morceau.
La colle JS
Le navigateur expose document, fetch, console, Canvas, WebGPU, Web Audio et des centaines d’autres APIs sous une forme historiquement pensée avec JavaScript.
Wasm peut les atteindre, évidemment. Des applications lourdes le font depuis des années. Mais elles passent par des bindings, cette couche de colle qui transforme les valeurs d’un monde vers l’autre.1
Une chaîne illustre bien le problème. Dans la mémoire linéaire de Wasm, elle ressemble à des octets à une adresse donnée. console.log, lui, attend une chaîne comprise par le moteur JavaScript. Le binding doit donc lire l’adresse et la longueur, créer une vue sur la mémoire, décoder les octets, puis appeler console.log avec le résultat.1
Dans l’autre sens, retourner une chaîne vers Wasm peut demander d’allouer de la mémoire dans le module, de réencoder le texte, d’écrire les octets au bon endroit et de définir qui devra ensuite libérer l’allocation.1
Les outils masquent cette mécanique. Emscripten possède embind, Rust utilise largement wasm-bindgen, et personne n’a envie de réécrire ces ponts à la main pour chaque propriété du DOM.1
Mais masquer une colle ne la supprime pas.
45 %
Mozilla donne un exemple ancien, particulièrement utile puisqu’il isole ce coût.
En 2020, l’équipe a utilisé une application TodoMVC en Rust avec le framework expérimental Dodrio. Une version appliquait les modifications DOM en appelant du JavaScript pour chaque opération. L’autre utilisait un binding direct expérimental, afin que le code Wasm déclenche les opérations DOM sans passer par cette colle.1
Dans cette expérience, le temps nécessaire pour appliquer les changements au DOM a baissé de 45 % lorsque la colle JavaScript a été retirée.1

Le chiffre ne veut pas dire « WebAssembly est deux fois plus rapide que JavaScript ». Le benchmark mesure un cas très précis, avec une architecture et un moteur de l’époque. Mozilla l’utilise pour montrer quelque chose de plus étroit : la frontière peut coûter cher même lorsque l’appel Wasm lui-même est rapide.1
C’est aussi pourquoi les applications graphiques, créatives ou techniques ont une relation bizarre avec Wasm. Plus elles manipulent Canvas, DOM, fichiers, audio, GPU ou événements, plus la partie « calcul rapide » doit communiquer avec une plateforme qui parle d’abord JavaScript.
Le faux manque
On pourrait imaginer que WebAssembly reste marginal à cause d’un langage bas niveau trop pauvre.
C’était beaucoup plus vrai au début. Depuis, le cœur a accumulé SIMD, exceptions, références, retours multiples, tail calls, GC, memory64 et d’autres extensions.1 D’autres travaux restent importants, notamment le stack switching et l’amélioration des threads, mais Mozilla considère le langage assez mûr pour déplacer l’attention vers son intégration Web.1
Ce changement de diagnostic est intéressant : ajouter une instruction Wasm de plus ne rendra pas MDN lisible depuis Rust, n’éliminera pas wasm-bindgen et ne transformera pas document.createElement en API native de tous les langages.
Le goulet est devenu social et architectural autant que technique.
Les mainteneurs de rustc ou LLVM veulent produire un artefact standard. Ils n’ont pas forcément envie de maintenir un deuxième backend implicite qui génère du JavaScript spécifique au navigateur. Aujourd’hui, ce travail finit donc souvent dans des distributions et outils tiers, différents pour Rust, C++, C# ou d’autres écosystèmes.1
Et la documentation Web reste, logiquement, écrite d’abord pour JavaScript. Pour utiliser une nouvelle API depuis un langage compilé en Wasm, il faut souvent comprendre sa forme JS avant de comprendre sa traduction dans le binding choisi.1
Les composants
La piste poussée par Mozilla est le WebAssembly Component Model.14
L’idée n’est pas simplement de mettre plusieurs .wasm dans un zip plus chic. Un composant décrit une interface de haut niveau autour d’un programme Wasm, avec WIT comme langage d’interface, un ABI canonique et des règles permettant à plusieurs langages et runtimes de se comprendre.4
C’est précisément le niveau qui manque entre « mon compilateur sait produire Wasm » et « mon programme sait appeler le Web ».
Dans le scénario Mozilla, le navigateur disposerait d’interfaces WIT dérivées des WebIDL qui définissent déjà les APIs Web. Un programme Rust pourrait demander une interface std:web/console, appeler une fonction avec une vraie chaîne de son langage et laisser le navigateur fournir le binding natif.1
Le composant pourrait ensuite être chargé comme un module. Mozilla montre même la forme idéale : un <script type="module" src="component.wasm">, sans fichier JavaScript compagnon.1
Si cela fonctionne, le changement dépasse la suppression de quelques lignes de JS. Un compilateur standard pourrait produire un artefact auto-contenu avec une interface portable ; le navigateur saurait le lier ; plusieurs langages réutiliseraient la même description des APIs ; et la frontière ne serait plus un bricolage différent pour chaque écosystème.14
Pas encore
Il faut résister à la tentation de présenter ce futur comme une feature de Firefox à activer demain matin.
Mozilla écrit noir sur blanc que la manière de brancher les Components à la plateforme Web n’est pas entièrement conçue, que l’outillage évolue et que son exemple std:web/console n’existe pas aujourd’hui.1
Le Component Model est bien une proposition suivie par le WebAssembly Community Group, et son dépôt publie désormais des jalons WASI Developer Preview avec WIT, linking, ressources et support asynchrone/concurrent.4 L’architecture sert donc déjà hors navigateur, ce qui ne signifie pas que les navigateurs aient adopté le binding Web natif imaginé par Mozilla.
Dans un navigateur, on passe aujourd’hui par Jco et son polyfill pour faire fonctionner les Components, précisément en l’absence de l’intégration native visée.1
Même le chantier plus modeste de l’intégration ESM montre ce décalage. En 2026, Mozilla a fait entrer les source-phase imports dans Firefox, tandis que l’instanciation/evaluation phase reste un travail distinct.56 La proposition ESM elle-même est toujours en phase 3.23
Le <script> du titre n’est donc pas une métaphore très lointaine. C’est littéralement l’une des syntaxes que la proposition veut rendre naturelle. Mais le chemin entre « proposition » et « comportement disponible partout » reste ouvert.
Le vrai gain
WebAssembly a déjà prouvé qu’une page pouvait accueillir des moteurs 3D, des codecs, des logiciels créatifs, des bibliothèques scientifiques et même des programmes venus d’autres plateformes.
Le prochain saut est moins spectaculaire sur une slide de benchmark. Il consiste à faire en sorte que ces programmes cessent de demander la permission à JavaScript pour exister comme programmes Web.
Cela réduirait le build tooling, la colle runtime et une partie du coût à la frontière. Mais le changement le plus profond serait peut-être ailleurs : un développeur Rust, C++, C# ou d’un autre langage pourrait apprendre les APIs du Web comme des APIs de sa plateforme, au lieu d’apprendre d’abord leur incarnation JavaScript puis le traducteur particulier de son écosystème.1
Depuis 2017, Wasm s’est rapproché du natif instruction après instruction. En 2026, Mozilla pose une question presque inverse : et s’il devait maintenant se rapprocher du Web, non plus en vitesse, mais en statut ?
