Die CEF-Wette: Deno Desktops Mittelweg

Die CEF-Wette: Deno Desktops Mittelweg

DenoDesktopCEFElectronTauri

Quellen:HN + Lobsters · HN

Im Juni 2026 veröffentlichte Deno mit v2.9.0 offiziell deno desktop – ein Befehl, der jedes TypeScript-Projekt (ein einzelnes Skript, eine Next.js-Anwendung oder sogar einen HTTP-Server) in ein macOS .app, ein Windows .exe und ein Linux AppImage packt. Auf HN erhielt es 997 Punkte und 365 Kommentare, auf Lobsters △34. Die hohe Punktzahl lag nicht nur an Denos Bekanntheit – die hitzigste Diskussion in den Kommentaren drehte sich um eine technische Entscheidung, die Deno getroffen hatte: Standardmäßige Bündelung von CEF (Chromium Embedded Framework) anstelle der Nutzung des systemeigenen WebViews wie bei Tauri.

Diese Wahl erntete in der Community sowohl Beifall als auch Kritik. Beifall von Entwicklern, die auf Linux mit webkitgtk schlechte Erfahrungen gemacht hatten; Kritik von denen, die meinten: »Warum den systemeigenen Browser-Engine nicht nutzen, wenn es ihn gibt?« Beide Seiten haben ihre Berechtigung, und Denos Wahl steht genau in der Mitte.

Electrons 200-MB-Fluch

Electron beherrscht die Desktop-Entwicklung aus einem einfachen Grund: Du schreibst die UI mit HTML/CSS/JS, rufst System-APIs mit Node.js auf, und ein Code läuft auf Windows/macOS/Linux. Der Preis ist ebenfalls einfach: Jede Electron-Anwendung ist eine eigenständig ausgelieferte Kopie von Chromium plus Node.js – Start bei 150 MB, Obergrenze bei 250 MB. Slack, VS Code, Discord, Figma – auf deiner Festplatte liegen vielleicht fünf Electron-Apps, was bedeutet, dass du fünf Kopien von Chromium gespeichert hast.

Das ist nicht nur Platzverschwendung. Jede Electron-App startet ihren eigenen Satz an Browser-Prozessen – GPU-Prozess, Renderer-Prozess, Netzwerkprozess – die Speichernutzung addiert sich linear. Ein Chrome-Tab verbraucht etwa 100 MB RAM; drei Electron-Apps gleichzeitig fressen locker 1,5 GB oder mehr. Der Nutzer denkt: »Warum frisst meine Notizen-App mehr Speicher als meine IDE?«, während die Wahrheit ist, dass deine Notizen-App einfach ein IDE-würdiger Browser-Host ist, der zufällig ein <textarea> ausführt.

Das Electron-Team kennt das Problem. Sie experimentierten mit electron-shared-library, um mehreren Electron-Apps das Teilen einer Chromium-Dynamic-Library zu ermöglichen, aber letztlich wurde es nie ausgerollt. Das grundlegende Hindernis ist nicht technischer Natur – es liegt im Version-Dependency-Hell der einzelnen Anwendungen. App A hängt von Electron 28 ab, App B von Electron 31 – die ABI-Kompatibilität einer Shared Library ist bei Chromiums Release-Rhythmus (alle vier Wochen ein Major Release) kaum aufrechtzuerhalten. Die Paketmanager der Linux-Distributionen lösen das, indem sie die gesamte Distribution auf einem einzigen Versions-Snapshot einfrieren – aber Desktop-Anwendungen haben diesen Luxus nicht: Du kannst nicht von einem Benutzer verlangen, VS Code zwangsweise zu aktualisieren, nur weil Discord ein Update bekommen hat.

Tauris System-WebView-Ansatz: Idee richtig, Praxis grausam

Tauri ging einen anderen Weg. Seine Kerneinsicht ist: Da das Betriebssystem bereits eine Browser-Engine eingebaut hat, warum noch eine ausliefern? macOS hat WKWebView, Windows hat WebView2, Linux hat webkit2gtk. Tauris Binärgröße ist extrem klein – Start unter 10 MB – denn die Rendering-Engine wird komplett an das Betriebssystem delegiert. Das Backend wird in Rust geschrieben, das Frontend kann jedes JS-Framework sein, und die IPC erfolgt über Tauris eigene Bridge.

Dieser Ansatz funktioniert unter Windows recht gut. WebView2 basiert auf Edge Chromium, Microsoft liefert Updates über Windows Update aus – relativ aktuelle Version, gute Kompatibilität. Die Probleme liegen bei macOS und Linux.

Unter macOS ist WKWebView an die Betriebssystemversion gebunden. Wenn dein Nutzer noch auf macOS 13 hängt, läuft deine Tauri-App mit der WebKit-Version von macOS 13 – die möglicherweise zwei bis drei Major Releases hinter dem neuesten Safari zurückliegt. Neue CSS-Features werden nicht unterstützt, neue Web-APIs sind nicht verfügbar, manche Canvas/WebGL-Verhaltensweisen weichen von Chrome ab. Tauri-Entwickler können nichts dagegen tun – sie haben weder die Fähigkeit noch die Erlaubnis, das systemeigene WebKit auf dem Rechner des Nutzers auszutauschen. Der Update-Rhythmus von Apples WKWebView liegt vollständig außerhalb der Kontrolle des App-Entwicklers.

Unter Linux ist die Situation noch schlimmer. Linux hat kein Konzept einer »systemweiten Browser-Engine« – verschiedene Desktop-Umgebungen, verschiedene GTK-Versionen, verschiedene von den Distributionen gepackte webkit2gtk-Versionen. In den HN-Kommentaren zu Deno Desktop schrieb ein langjähriger Tauri-Entwickler namens echelon eine vielzitierte Bewertung: webkitgtk sei »langsam und speicherhungrig«. Das ist keine persönliche Beschwerde – Tauris GitHub Issues #3988 und #7021 dokumentieren schwere Performance-Einbußen von webkit2gtk auf Linux bei vielen DOM-Elementen, darunter ruckelndes Scrollen, ausgelassene Frames und eine bekannte Performance-Regression, die mit WebKit 2.40 eingeführt wurde.

Tauris eigentliches Problem auf Linux ist: Es gibt schlicht keine verlässliche Rendering-Engine zur Auswahl. webkit2gtk wird von der WebKitGTK-Community gewartet, deren Entwicklungsressourcen bei weitem nicht an das Chromium-Team heranreichen – Chromium hat ein Vollzeit-Entwicklerteam und Sicherheitsforscher von Google; die Kern-Maintainer von WebKitGTK lassen sich an einer Hand abzählen. Das ist keine Herabwürdigung der Fähigkeiten der WebKitGTK-Entwickler – sie leisten bewundernswerte Arbeit –, aber das Kräfteverhältnis ist eine objektive Tatsache.

Denos Wahl: CEF bündeln, aber nicht exklusiv

Deno Desktop wählte den dritten Weg. Es verwendet standardmäßig CEF (Chromium Embedded Framework) – genau wie Electron auf Chromium basierend, aber mit zwei entscheidenden Unterschieden.

Erstens: CEF ist eine reine Browser-Engine ohne Node.js. Electrons Bundle enthält sowohl die Chromium-Rendering-Engine als auch die Node.js-Laufzeit, die über libnode eng gekoppelt sind. Die Architektur von Deno Desktop ist anders: Deno selbst ist die JS/TS-Laufzeit (basiert auf V8), und CEF ist nur für das Rendern der HTML/CSS/JS-Frontend-Seiten zuständig. Der Deno-Prozess läuft nicht innerhalb von CEF – er startet als eigenständiger Prozess einen lokalen HTTP-Server, und das CEF-Fenster lädt http://localhost:<port>, um die UI zu rendern. Die Kommunikation zwischen Frontend und Backend erfolgt über normale HTTP/WebSocket-Verbindungen, nicht über die prozessinterne Bridge von Electron via ipcMain/ipcRenderer.

Eine direkte Konsequenz dieser Architektur: Deno Desktop-Anwendungen können zu anderen Rendering-Backends wechseln. Deno unterstützt drei Backends: cef (Standard), webview (systemeigenes WebView) und winit (reines Rust-Fenster, geeignet für Spiele/Grafikanwendungen). CEF ist die offiziell empfohlene Standardoption, aber wenn dir Kompatibilität egal ist, kannst du zu webview wechseln und von der kleineren Binärgröße profitieren. Diese Flexibilität hat Electron nicht – Electrons Chromium-Bindung ist zu tief, ein »Wegschalten« ist unmöglich.

Zweitens: Denos öffentliche Roadmap enthält einen klar formulierten Punkt: gemeinsame CEF-Laufzeit. Derzeit bündelt jede Deno Desktop-Anwendung immer noch ihre eigene Kopie der CEF-Dynamic-Library, aber das Deno-Team plant, in Zukunft eine »verwaltete gemeinsame Laufzeit« zu implementieren – mehrere Deno Desktop-Anwendungen teilen sich eine einzige CEF-Installation auf dem Rechner. Diese Richtung entspricht dem shared-library-Experiment, das Electron versucht, aber aufgegeben hat – aber Deno hat einen Vorteil, den Electron nicht hat: Alle Deno Desktop-Anwendungen laufen unter demselben Versionsverwaltungsrahmen. Denos Update-Mechanismus kann sicherstellen, dass »wenn auf deinem Rechner zwei Deno Desktop-Anwendungen installiert sind, die verwendete CEF-Version von Deno einheitlich verwaltet wird« – ähnlich wie ein systemweiter Paketmanager Shared-Library-Versionen verwaltet. Das ist kein bereits gelöstes Problem – ein Eintrag auf der Roadmap ist nicht gleichbedeutend mit einer Auslieferung –, aber die Richtung stimmt.

Technische Merkmale von CEF

CEF selbst ist ein sehr ausgereiftes Projekt. Spotify Desktop Client, Teile von Adobe Creative Cloud, Epic Games Launcher, die Browser-Quellen von OBS Studio – sie alle nutzen CEF, um Chromium einzubetten. Seine Multi-Prozess-Architektur entspricht der von Chrome: Ein Browser-Prozess verwaltet Fenster und Netzwerk, jede Seiteninstanz läuft in einem eigenen Renderer-Prozess, und der GPU-Prozess ist für Compositing und Hardwarebeschleunigung zuständig. Die daraus resultierende Isolierung ergänzt Denos Sicherheitsmodell perfekt – Deno verbietet standardmäßig Dateisystem-/Netzwerk-/Umgebungsvariablen-Zugriffe, und CEFs Sandbox-Renderer-Prozess schränkt die Ausbruchsmöglichkeiten des Frontend-Codes weiter ein.

CEF unterstützt auch Off-Screen Rendering (OSR). Im normalen Modus erstellt CEF native Fenster und rendert darin; im OSR-Modus wird das Renderergebnis in einen Speicherpuffer ausgegeben, und die Host-Anwendung entscheidet, wie es angezeigt wird. Diese Fähigkeit ist wichtig für Deno Desktops winit-Backend – falls Deno in Zukunft vollständig benutzerdefinierte UI-Frameworks (z. B. GPU-betriebene UIs) unterstützen möchte, kann der OSR-Modus von CEF Webinhalte direkt als Textur in die Rendering-Pipeline einspeisen.

Aber CEF ist nicht ohne Kosten. Eine CEF-Dynamic-Library (libcef.so) ist etwa 150 MB groß, plus Chromium-Ressourcendateien (.pak, icudtl.dat, Locales) – der gesamte Speicherplatzverbrauch liegt bei etwa 200 MB. Das ist vergleichbar mit Electron. Rein von der Binärgröße her ist Deno Desktop + CEF nicht leichter als Electron – seine Stärke liegt woanders. Die Stärke liegt erstens darin, dass CEF gemeinsam genutzt werden kann, während Electrons Node.js+Chromium-Verbund schwer zu teilen ist, und zweitens darin, dass Deno es dir erlaubt, für extreme Kompaktheit auf das webview-Backend zurückzugreifen – Electron hat diese Option nicht.

Vergleich der drei Ansätze

In einer Tabelle werden die jeweiligen Abwägungen deutlich:

DimensionElectronTauriDeno Desktop (CEF)
Rendering-EngineGebündeltes ChromiumSystem-WebViewGebündeltes CEF (umschaltbar auf System-WebView)
Backend-SpracheNode.js (JS)RustDeno (JS/TS)
Binärgröße150–250 MB3–15 MB200 MB (CEF-Modus) / 15 MB (WebView-Modus)
macOS-KompatibilitätAktuelles Chromium, nicht OS-limitiertDurch System-WKWebView-Version limitiertAktuelles CEF, nicht OS-limitiert
Linux-KompatibilitätEinheitlichAbhängig von webkit2gtk, Performance und Kompatibilität schwankendEinheitlich (eigenes CEF)
ProzessmodellMain + Renderer (Node.js und Chromium eng gekoppelt)Rust-Hauptprozess + System-WebView-ProzessDeno-HTTP-Server-Prozess + CEF-Browser/Renderer-Prozesse
Potenzial für gemeinsame EngineNiedrig (starke Versions-Fragmentierung)Natürlich gemeinsam (nutzt System-Engine)Mittel (Shared-Runtime in der Roadmap)
Frontend-Framework-SupportBeliebiges JS-FrameworkBeliebiges JS-FrameworkBeliebiges JS-Framework (inkl. Next.js etc.)
Update-MechanismusEigenbau erforderlichEigenbau erforderlichIntegriert (Deno-Deploy-artiges Hot-Update)

Die am leichtesten misszuverstehende Zeile dieser Tabelle ist die zur Binärgröße. Deno Desktop sieht mit 200 MB im CEF-Modus genauso schlecht aus wie Electron – aber der entscheidende Unterschied ist, welcher Teil dieser 200 MB »variabler Code« und welcher Teil »gemeinsam nutzbare Engine« ist. Bei Electron entfallen etwa 180 MB der 200 MB auf Chromium + Node.js, und jede Anwendung wird eigenständig gepackt. Bei Deno Desktop entfallen etwa 150 MB der 200 MB auf CEF, aber die Roadmap für eine gemeinsame Laufzeit bedeutet, dass dieser Teil in Zukunft nur einmal gespeichert werden müsste. Bevor die gemeinsame Laufzeit Realität ist, hat Deno Desktop volumenseitig nicht gegen Electron gewonnen; nach ihrer Einführung hat es das Potenzial, den inkrementellen Platzverbrauch jeder Anwendung auf ein paar MB zu drücken – so, wie Tauri es heute schon schafft, aber ohne die Konsistenz der Rendering-Engine zu opfern.

Gemeinsame Abhängigkeiten: Eine von Desktop-Anwendungen vergessene Linux-Weisheit

Linux-Distributionen lösen das Problem gemeinsamer Abhängigkeiten mit Paketmanagern seit dreißig Jahren. libssl.so, libgtk.so, libc.so – auf dem System gibt es immer genau eine Kopie, und alle Anwendungen linken gegen dieselbe. Version-Upgrades werden vom Paketmanager koordiniert, die ABI-Kompatibilität wird auf Distributionsebene garantiert. Dieses System funktioniert so gut, dass Linux-Nutzer eine natürliche Abneigung dagegen haben, dass jede Anwendung ihre eigene OpenSSL mitbringt.

Warum erfinden Desktop-Anwendungen dieses Rad neu? Der Grund liegt im unterschiedlichen Vertrauensmodell, nicht in technischer Naivität. Der Linux-Paketmanager kann nur funktionieren, weil es eine zentrale Autorität gibt (die Distributions-Maintainer), die für die Versionskonsistenz aller Pakete verantwortlich ist. Das Ökosystem der Desktop-Anwendungen hat diese zentrale Autorität nicht – VS Code kommt von Microsoft, Discord von der Discord Inc., Figma von der Figma Inc. Es gibt keinen Koordinationsmechanismus zwischen ihnen. Jeder Anwendungsentwickler muss annehmen: »Ich weiß nicht, was auf dem Rechner des Nutzers installiert ist«, und wählt daher die konservativste Strategie: Alles, was ich brauche, packe ich mit rein.

Deno Desktops Plan einer gemeinsamen CEF-Laufzeit versucht, einen Mittelweg zwischen diesen beiden Extremen zu finden: Keine systemweite, globale Freigabe (dafür wäre eine Koordination auf Betriebssystemebene nötig), sondern nur eine verwaltete Freigabe innerhalb des Deno-Ökosystems. Alle Anwendungen, die mit deno desktop gebaut und verteilt werden, haben ihre CEF-Version durch Denos einheitlichen Versionsmanager unter Kontrolle. Das erinnert an Flatpaks Runtime-Mechanismus – mehrere Flatpak-Anwendungen teilen sich eine KDE/GNOME Runtime –, nur mit feinerer Granularität (nur die Browser-Engine wird geteilt).

Ob dieser Weg gangbar ist, hängt von zwei Variablen ab: Erstens, ob das Deno-Desktop-Ökosystem genügend Anwendungen hervorbringt, um die gemeinsame Nutzung sinnvoll zu machen (wenn es nur drei Deno-Desktop-Anwendungen gibt, ist der Nutzen einer gemeinsamen Runtime verschwindend gering). Zweitens, ob die ABI-Stabilität von CEF die Situation »mehrere Anwendungen hängen von derselben CEF-Version ab, haben aber unterschiedliche Update-Frequenzen« aushält. Die API-Stabilität von CEF ist besser als die von Chromium selbst – die API-Wrapper-Schicht von CEF puffert viel ab –, aber sie ist nicht in Stein gemeißelt. Bei einem CEF-Major-Update stellt sich die Frage, wie der Shared-Runtime-Manager mit dem Fall umgeht, dass »App A mit der neuen Version kompatibel ist, App B aber nur mit der alten« – und das Deno-Team hat bisher keinen technischen Plan dafür veröffentlicht.

Der entscheidende Faktor dieser Wette

echelons Kommentar auf HN zeigte, warum Denos Wahl von CEF die richtige Richtung ist: Die Erfahrungen mit Tauris systemeigenem WebView auf macOS und Linux sind zu schmerzhaft. Tauris Ansatz ist theoretisch sauber – verwende, was das System bietet, liefer keine doppelten Binärdateien aus –, aber die Realität ist, dass der Update-Rhythmus von WKWebView auf macOS von Apple bestimmt wird und die Qualität von webkit2gtk auf Linux von einer kleinen Open-Source-Community garantiert wird. Die theoretische Sauberkeit kann nicht die raue Praxis entschädigen – der Nutzer wird sich nur merken, dass »diese App auf Linux unbenutzbar ruckelt«, nicht, dass »diese App das systemeigene WebView verwendet und daher weniger Speicherplatz braucht«.

Denos CEF-Ansatz opfert die theoretische Reinheit und gewinnt dafür praktische Kontrollierbarkeit. Er erkennt eine peinliche, aber wahre technische Tatsache an: Im Bereich plattformübergreifender Desktop-Anwendungen ist Kontrollierbarkeit wichtiger als Größe. Wenn eine Rendering-Engine auf Plattformen, die du nicht kontrollierst, inkonsistent funktioniert, wird der eingesparte Speicherplatz durch die Entwicklungszeit, die für die Behebung von Kompatibilitätsproblemen draufgeht, um ein Vielfaches aufgefressen.

Doch Deno hat die Größenoptimierung nicht aufgegeben – die Roadmap für eine gemeinsame CEF-Laufzeit ist der fundamentale Unterschied zu Electron. Wenn die gemeinsame CEF-Laufzeit erfolgreich umgesetzt wird, hätte Deno Desktop gleichzeitig »Konsistenz der Rendering-Engine« (durch gebündeltes CEF) und »kleine inkrementelle Größe« (durch die Shared Architecture) – etwas, das weder Electron (nur Konsistenz, keine kleine Größe) noch Tauri (nur auf Windows kleine Größe, keine Konsistenz auf macOS/Linux) für sich allein erreichen konnten.

Natürlich darf man Dinge auf einer Roadmap nicht als bereits ausgeliefert bewerten. Deno Desktop ist derzeit noch eine Canary-Version, die API ist nicht stabil, und die gemeinsame Laufzeit ist ein »Zukunftsplan«. In diesem Bereich hat es nie an schönen Architekturdiagrammen gemangelt – es mangelt an Teams, die das scheinbar einfache, in Wirklichkeit aber höllisch schwierige Problem der gemeinsamen Engine-Versionsverwaltung wirklich ingenieurtechnisch umsetzen können. Das Deno-Team hat die Fähigkeiten dafür (Denos eigenes Versionsmanagement und Remote-Modul-Caching-System sind eine nutzbare Infrastrukturgrundlage), aber die Distanz zwischen Fähigkeit und Auslieferung ist der Kern der Wette.