En juin 2026, Deno a officiellement publié deno desktop dans sa version 2.9.0 — une commande qui transforme n’importe quel projet TypeScript (script fichier unique, application Next.js, voire un serveur HTTP) en une application macOS .app, Windows .exe et Linux AppImage. Sur HN, 997 points et 365 commentaires ; sur Lobsters, △34. Ce score élevé n’est pas dû seulement à la notoriété de Deno — la discussion la plus animée dans les commentaires portait sur un choix technique de Deno : intégrer par défaut CEF (Chromium Embedded Framework), plutôt que de dépendre du WebView système comme le fait Tauri.
Ce choix a recueilli à la fois des applaudissements et des critiques dans la communauté. Les applaudissements viennent des développeurs qui ont souffert de webkitgtk sous Linux ; les critiques viennent de ceux qui se demandent « pourquoi ne pas utiliser le moteur de navigateur intégré au système ? ». Les deux voix ont raison, et le choix de Deno se situe précisément entre elles.
La malédiction des 200 Mo d’Electron
Electron domine le développement d’applications de bureau pour une raison simple : vous écrivez l’interface utilisateur en HTML/CSS/JS, vous appelez les API système avec Node.js, et un seul code fonctionne sur Windows/macOS/Linux. Le prix est tout aussi simple : chaque application Electron est une copie indépendante du navigateur Chromium, accompagnée de l’environnement d’exécution Node.js, commençant à 150 Mo pour atteindre 250 Mo. Slack, VS Code, Discord, Figma — vous avez peut-être cinq applications Electron sur votre disque dur, ce qui signifie cinq copies de Chromium.
Ce n’est pas seulement un gaspillage d’espace disque. Chaque application Electron lance son propre ensemble de processus de navigateur — processus GPU, processus de rendu, processus réseau — la consommation mémoire s’ajoute linéairement. Un onglet Chrome consomme environ 100 Mo de mémoire ; trois applications Electron en cours d’exécution consomment facilement plus de 1,5 Go. La perception de l’utilisateur est « pourquoi mon logiciel de notes consomme-t-il plus de mémoire que mon IDE ? », alors qu’en réalité, votre logiciel de notes est un hôte de navigateur de niveau IDE, qui exécute simplement une <textarea>.
L’équipe Electron n’ignore pas le problème. Ils ont expérimenté avec electron-shared-library, essayant de faire partager une seule bibliothèque dynamique Chromium par plusieurs applications Electron, mais cela n’a jamais abouti. L’obstacle fondamental n’est pas technique — il réside dans l’enfer des dépendances de version propres à chaque application. L’application A dépend d’Electron 28, l’application B d’Electron 31 ; la compatibilité ABI d’une bibliothèque partagée est presque impossible à maintenir face au rythme de mise à jour de Chromium (une version majeure toutes les quatre semaines). Les gestionnaires de paquets des distributions Linux résolvent ce problème en « verrouillant toute la distribution sur un instantané de version », mais les applications de bureau n’ont pas ce luxe — vous ne pouvez pas exiger d’un utilisateur qu’il mette à jour VS Code simplement parce que Discord a été mis à jour.
La voie du WebView système de Tauri : idée juste, pratique cruelle
Tauri a emprunté une autre voie. Son insight fondamental est : puisque le système d’exploitation intègre déjà un moteur de navigateur, pourquoi en distribuer un autre ? macOS a WKWebView, Windows a WebView2, Linux a webkit2gtk. La taille du binaire Tauri est extrêmement petite — moins de 10 Mo au départ — car le moteur de rendu est entièrement externalisé vers le système d’exploitation. Le backend est écrit en Rust, le frontend peut être n’importe quel framework JS, et l’IPC est assuré par un pont Tauri personnalisé.
Cette idée fonctionne bien sous Windows. WebView2 est basé sur Edge Chromium, Microsoft le met à jour via Windows Update, la version est récente et la compatibilité bonne. Le problème se pose sur macOS et Linux.
Sur macOS, WKWebView est lié à la version du système d’exploitation. Cela signifie que si votre utilisateur utilise encore macOS 13, votre application Tauri utilise la version de WebKit correspondant à macOS 13 — cette version peut accuser un retard de deux à trois versions majeures par rapport au Safari le plus récent. Les nouvelles fonctionnalités CSS ne sont pas supportées, les nouvelles API Web ne sont pas exposées, certains comportements Canvas/WebGL diffèrent de Chrome. Les développeurs Tauri ne peuvent rien y faire — ils n’ont ni la capacité ni la permission de remplacer le WebKit système sur la machine de l’utilisateur. Le rythme de mise à jour de WKWebView par Apple échappe totalement au contrôle du développeur d’application.
La situation est pire sous Linux. Linux n’a pas de concept de « moteur de navigateur système » — les différents environnements de bureau, les différentes versions de GTK, les versions de webkit2gtk empaquetées par les différentes distributions varient toutes. Dans les commentaires HN de Deno Desktop, un développeur Tauri de longue date, echelon, a écrit une évaluation fréquemment citée : webkitgtk est « lent et gourmand en mémoire ». Ce n’est pas une plainte personnelle — les issues GitHub #3988 et #7021 de Tauri documentent de graves dégradations de performance de webkit2gtk sous Linux avec un grand nombre d’éléments DOM, y compris des saccades de défilement, des chutes d’images de rendu, et une régression de performance connue introduite par WebKit 2.40.
**Le vrai problème de Tauri sous Linux est qu’il n’existe tout simplement pas de moteur de rendu fiable. ** webkit2gtk est maintenu par la communauté WebKitGTK, dont les ressources de développement sont bien inférieures à celles de l’équipe Chromium — Chromium bénéficie d’ingénieurs à plein temps et de chercheurs en sécurité chez Google, tandis que les mainteneurs principaux de WebKitGTK se comptent sur les doigts d’une main. Il ne s’agit pas de dénigrer les compétences des développeurs de WebKitGTK — ils font un travail respectable — mais le rapport de force est un fait objectif.
Le choix de Deno : intégrer CEF, sans l’exclusivité
Deno Desktop a choisi une troisième voie. Par défaut, il utilise CEF (Chromium Embedded Framework) — basé sur Chromium comme Electron, mais avec deux différences clés.
Premièrement, CEF est un pur moteur de navigateur, sans Node.js. Le bundle Electron contient à la fois le moteur de rendu Chromium et l’environnement d’exécution Node.js, profondément couplés via libnode. L’architecture de Deno Desktop est différente : Deno lui-même est l’environnement d’exécution JS/TS (basé sur V8), et CEF ne se charge que du rendu des pages frontend HTML/CSS/JS. Le processus Deno ne s’exécute pas à l’intérieur de CEF — il démarre un serveur HTTP local en tant que processus indépendant, et la fenêtre CEF charge http://localhost:<port> pour afficher l’interface utilisateur. La communication frontend-backend passe par HTTP/WebSocket classique, et non par un pont intra-processus comme le ipcMain/ipcRenderer d’Electron.
Une conséquence directe de ce choix architectural est : les applications Deno Desktop peuvent basculer vers d’autres backends de rendu. Deno prend en charge trois backends : cef (par défaut), webview (WebView système), et winit (fenêtre Rust pure, adaptée aux jeux/applications graphiques). CEF est l’option par défaut recommandée, mais si la compatibilité n’est pas une préoccupation, on peut passer à webview pour un binaire plus léger. Cette flexibilité n’existe pas dans Electron — la liaison de Chromium dans Electron est trop profonde pour pouvoir « basculer ».
Deuxièmement, la feuille de route publique de Deno mentionne clairement un runtime CEF partagé. Actuellement, chaque application Deno Desktop embarque sa propre copie de la bibliothèque dynamique CEF, mais l’équipe Deno prévoit à l’avenir de mettre en œuvre un « runtime partagé géré » — plusieurs applications Deno Desktop partageraient une seule installation de CEF sur la machine. Cette voie est similaire à l’expérience shared-library qu’Electron a tentée puis abandonnée, mais Deno a un avantage qu’Electron n’a pas : toutes les applications Deno Desktop s’exécutent sous le même cadre de gestion de version du runtime. Le mécanisme de mise à jour de Deno peut garantir que « si votre machine a deux applications Deno Desktop, la version de CEF qu’elles utilisent est gérée de manière unifiée par Deno », un peu comme un gestionnaire de paquets système gère les versions des bibliothèques partagées. Ce n’est pas un problème résolu — une entrée sur une feuille de route n’équivaut pas à une livraison — mais la direction est la bonne.
Les caractéristiques techniques de CEF
CEF est un projet extrêmement mature. Le client de bureau Spotify, certains composants d’Adobe Creative Cloud, Epic Games Launcher, la source navigateur d’OBS Studio — tous utilisent CEF pour intégrer Chromium. Son architecture multi-processus est identique à celle de Chrome : un processus browser gère les fenêtres et le réseau, chaque instance de page s’exécute dans un processus renderer indépendant, et le processus GPU est responsable de la composition et de l’accélération matérielle. L’isolement offert par cette architecture est complémentaire du modèle de sécurité de Deno — Deno interdit par défaut l’accès au système de fichiers, au réseau et aux variables d’environnement, et le processus sandboxé du renderer CEF limite encore davantage la surface de fuite du code frontend.
CEF prend également en charge le rendu hors écran (Off-Screen Rendering, OSR). En mode normal, CEF crée une fenêtre native et y effectue le rendu ; en mode OSR, le résultat du rendu est envoyé dans un tampon mémoire, et l’application hôte décide comment l’afficher. Cette capacité est importante pour le backend winit de Deno Desktop — si Deno souhaite à l’avenir prendre en charge des frameworks d’interface utilisateur entièrement personnalisés (comme une UI pilotée par GPU), le mode OSR de CEF peut directement intégrer le contenu web sous forme de texture dans le pipeline de rendu.
Mais CEF a aussi un coût. Une bibliothèque dynamique CEF (libcef.so) pèse environ 150 Mo, et avec les fichiers de ressources Chromium (.pak, icudtl.dat, locales), l’occupation disque totale est d’environ 200 Mo. C’est comparable à Electron. Rien qu’en termes de taille de binaire, Deno Desktop + CEF n’est pas plus léger qu’Electron — son avantage n’est pas là. Il réside dans deux points : d’une part, CEF peut être partagé, tandis que le couplage Node.js+Chromium d’Electron est difficile à partager ; d’autre part, Deno permet de descendre au backend webview pour rechercher un volume minimal, option qu’Electron n’offre pas.
Comparaison des trois approches
Placer les trois approches dans un même tableau permet de visualiser plus clairement leurs compromis respectifs.
| Dimension | Electron | Tauri | Deno Desktop (CEF) |
|---|---|---|---|
| Moteur de rendu | Chromium intégré | WebView système | CEF intégré (commutable vers WebView système) |
| Langage backend | Node.js (JS) | Rust | Deno (JS/TS) |
| Taille du binaire | 150-250 Mo | 3-15 Mo | 200 Mo (mode CEF) / 15 Mo (mode webview) |
| Compatibilité macOS | Chromium récent, pas de limitation OS | Limité par la version du WKWebView système | CEF récent, pas de limitation OS |
| Compatibilité Linux | Cohérente | Dépend de webkit2gtk, performances et compatibilité variables | Cohérente (CEF propre) |
| Modèle de processus | Main + Renderer (Node.js et Chromium profondément couplés) | Processus principal Rust + processus WebView système | Processus serveur HTTP Deno + processus CEF browser/renderer |
| Potentiel de moteur partagé | Faible (fragmentation des versions sévère) | Partagé par nature (moteur système) | Moyen (projet de runtime partagé dans la feuille de route) |
| Support des frameworks frontend | Tout framework JS | Tout framework JS | Tout framework JS (y compris frameworks full-stack comme Next.js) |
| Mécanisme de mise à jour | À construire | À construire | Intégré (mise à jour chaude de type Deno Deploy) |
La ligne la plus facile à mal interpréter dans ce tableau est celle de la « taille du binaire ». Les 200 Mo de Deno Desktop en mode CEF semblent aussi mauvais qu’Electron, mais la différence clé réside dans ce qui, dans ces 200 Mo, est « code variable » et ce qui est « moteur partageable ». Dans les 200 Mo d’Electron, Chromium + Node.js représente environ 180 Mo, et chaque application est empaquetée indépendamment. Dans les 200 Mo de Deno Desktop, CEF représente aussi environ 150 Mo, mais la feuille de route du runtime partagé de Deno signifie qu’à l’avenir, cette partie pourrait n’être stockée qu’une seule fois. Avant la mise en œuvre du runtime partagé, Deno Desktop ne bat pas Electron en termes de taille ; après la mise en œuvre du runtime partagé, il a le potentiel de réduire la taille incrémentale de chaque application à quelques Mo — comme le fait Tauri aujourd’hui, mais sans sacrifier la cohérence du moteur de rendu.
Dépendances partagées : une sagesse Linux oubliée par les applications de bureau
Les distributions Linux résolvent le problème des dépendances partagées avec leurs gestionnaires de paquets depuis trente ans. libssl.so, libgtk.so, libc.so — il n’y a toujours qu’une seule copie sur le système, et toutes les applications sont liées à cette même copie. Les mises à jour de version sont coordonnées par le gestionnaire de paquets, et la compatibilité ABI est assurée au niveau de la distribution. Ce mécanisme fonctionne si bien que les utilisateurs Linux ont une aversion naturelle pour l’idée que « chaque application embarque sa propre copie d’OpenSSL ».
Pourquoi les applications de bureau réinventent-elles cette roue ? La raison réside dans la différence de modèle de confiance, et non dans une naïveté technique. Le gestionnaire de paquets Linux fonctionne parce qu’il y a une autorité centrale (les mainteneurs de la distribution) responsable de la cohérence des versions de tous les paquets. L’écosystème des applications de bureau n’a pas cette autorité centrale — VS Code est publié par Microsoft, Discord par Discord Inc., Figma par Figma Inc., et il n’existe aucun mécanisme de coordination entre eux. Chaque développeur d’application ne peut que supposer « je ne sais pas ce qu’il y a sur la machine de l’utilisateur », et choisit donc la stratégie la plus conservatrice : empaqueter tout ce dont j’ai besoin.
Le projet de runtime CEF partagé de Deno Desktop tente de trouver un point médian entre ces deux extrêmes : ne pas faire de partage global au niveau système (cela nécessiterait une coordination au niveau du système d’exploitation), mais seulement un partage géré au sein de l’écosystème Deno. Toutes les applications construites et distribuées via deno desktop auront leur version de CEF contrôlée par le gestionnaire de versions unifié de Deno. Cela ressemble un peu au mécanisme de runtime de Flatpak — plusieurs applications Flatpak partagent un runtime KDE/GNOME — mais à une granularité plus fine, ne partageant que le moteur de navigateur.
La viabilité de cette voie dépend de deux variables : d’une part, que l’écosystème Deno Desktop génère suffisamment d’applications pour que le partage ait un sens (s’il n’y a que trois applications Deno Desktop, le gain d’un runtime partagé est négligeable) ; d’autre part, que la stabilité ABI de CEF puisse supporter une situation où « plusieurs applications dépendent de la même instance de CEF mais avec des fréquences de mise à jour différentes ». La stabilité de l’API de CEF est meilleure que celle de Chromium lui-même — la couche wrapper API de CEF amortit beaucoup de choses — mais elle n’est pas monolithique non plus. Lors d’une mise à jour majeure de CEF, la manière dont le gestionnaire de runtime partagé gérera le cas où « l’application A est compatible avec la nouvelle version, l’application B ne l’est pas » n’a pas encore été rendue publique par l’équipe Deno.
Le facteur décisif de ce pari
Le commentaire d’echelon sur HN explique pourquoi le choix de CEF par Deno est la bonne direction : l’expérience du WebView système de Tauri sur macOS et Linux a été trop douloureuse. L’idée de Tauri est propre — utiliser ce qui est natif au système, ne pas distribuer de binaires redondants — mais la réalité est que le rythme de mise à jour de WKWebView sur macOS est dicté par Apple, et la qualité de webkit2gtk sur Linux est garantie par une petite communauté open source. La pureté de l’idée ne compense pas la rugosité de l’implémentation — l’utilisateur se souvient seulement que « cette application est inutilisablement lente sous Linux », pas que « cette application utilise le WebView système donc elle économise de l’espace ».
La voie CEF de Deno abandonne la pureté conceptuelle en échange de la contrôlabilité de l’implémentation. Elle reconnaît un fait d’ingénierie gênant mais vrai : dans le domaine des applications de bureau multi-plateformes, la contrôlabilité est plus importante que la taille. Si un moteur de rendu se comporte de manière incohérente sur des plateformes que vous ne contrôlez pas, l’espace disque économisé sera compensé au centuple par le temps de développement consacré à résoudre les problèmes de compatibilité.
Mais Deno n’a pas non plus abandonné l’optimisation de la taille — la feuille de route du runtime partagé est sa différence fondamentale avec Electron. Si le runtime CEF partagé peut être mis en œuvre avec succès, Deno Desktop possédera à la fois la « cohérence du moteur de rendu » (grâce à l’intégration de CEF) et la « petite taille incrémentale » (grâce à l’architecture partagée), ce qu’Electron (seulement la cohérence, pas la petite taille) et Tauri (seulement la petite taille sous Windows, pas la cohérence sous macOS/Linux) n’ont pas réussi à faire chacun de leur côté.
Bien sûr, ce qui est sur une feuille de route ne peut pas être évalué comme quelque chose de livré. Deno Desktop est actuellement encore en version canary, l’API n’est pas stabilisée, et le runtime partagé est un « projet futur ». Ce domaine ne manque jamais de belles architectures — ce qui manque, ce sont des équipes capables de véritablement industrialiser et concrétiser ce problème apparemment simple mais diablement difficile qu’est la gestion de versions d’un moteur partagé. L’équipe Deno a les compétences nécessaires (la gestion de versions de Deno lui-même et le système de cache de modules distants sont une infrastructure dont on peut s’inspirer), mais la distance entre la capacité et la livraison, c’est le pari lui-même.