Deno 2.9 wurde am 2026-06-25 veröffentlicht, publiziert von Bartek Iwańczuk mit den Release-Notes auf deno.com und dem GitHub-Releases-API-Listing v2.9.0. Es ist das größte Deno-Release des Zyklus und das erste getaggte Build, das den deno-desktop-Subcommand enthält (die PR #33441 vom 16. Juni) sowie eine lange Liste von Supply-Chain-, Performance-, Test-Runner-, Web-Platform- und Node.js-Kompatibilitätsänderungen. Der Blogpost öffnet mit drei Zahlen, die das Release verankern: Der Cold Start fällt von 34,2 ms auf 17,3 ms (1,98x), der Spitzen-Resident-Set auf Deno.serve sinkt um 2,2x bei der Realworld-Last und um 3,1x bei 1-MiB-Bodies, und der Deno.serve-Durchsatz steigt um 1,27x in Realworld, 1,11x in Plaintext und 1,18x bei 1-MiB-Bodies. Hinter diesen Zahlen stehen vier primäre Perf-Änderungen (#34450, #35373, #35338, #35183), plus ein neuer Deno-eigener HTTP/1.1-Serving-Pfad (#34446) und Rust-Ports von crypto.subtle (#34966) und console / Deno.inspect (#35087).
Das 2.9-Release folgt auf Deno 2.8 am 1. Juni, das sich auf Audit-Fixes, CI-Tooling und den pack-Subcommand konzentrierte. Der 2.9-Zyklus hat eine andere Form: Über 165 PRs landen, die Perf-Gewinne sind der größte Einszyklus-Sprung seit zwei Jahren, und die Supply-Chain-Arbeit schließt die Lücke zu pnpm's minimumReleaseAge und pnpm's trustPolicy-Defaults.
Cold Start, Speicher und Durchsatz
Die Schlagzeilenzahlen kommen aus Deno's eigenem Benchmark-Harness, der drei Deno.serve-Lasten bei Concurrency 100 gegen Deno 2.8.0 auf einer dedizierten x86_64-Linux-Box ausführt, mit Server und Lastgenerator an disjunkten Cores gepinnt und oha-Median aus 3 Runs. Der Cold Start ist der Mittelwert aus 150 hyperfine-Runs eines Hello-World-Programms. Die komplette Auswahl:
| Last | Deno 2.8 | Deno 2.9 | Änderung |
|---|---|---|---|
| Cold Start (niedriger ist besser) | 34,2 ms | 17,3 ms | 1,98x schneller |
| Deno.serve Realworld (req/s, höher ist besser) | 56,8k | 72,4k | 1,27x |
| Deno.serve Plaintext (req/s) | 77,0k | 85,6k | 1,11x |
| Deno.serve 1-MiB-Body (req/s) | 1 617 | 1 907 | 1,18x |
| RSS, Realworld (niedriger ist besser) | 142 MB | 64 MB | 2,2x weniger Speicher |
| RSS, 1-MiB-Body | 197 MB | 63 MB | 3,1x weniger Speicher |
Der Cold-Start-Sturz ist die für sich genommen auffälligste Zahl. Der Gewinn kommt aus vier primären Änderungen. Erstens Lazy-Loading der node:-Globals aus dem Snapshot, damit der Snapshot selbst kleiner ist (#34450). Zweitens Gating des eifrigen Node-Bootstraps auf Node-Worker, sodass die Haupt-Isolate die Bootstrap-Kosten nicht mehr für Code zahlt, der node: nie berührt (#35373). Drittens ein V8-Codecache für träge geladene ESM-Module, sodass der zweite Start den Parse-and-Compile-Schritt überspringt (#35338). Viertens ein minifizierter Snapshot, der das On-Disk-Image komprimiert (#35183). Auf macOS verkürzen verkettete Fixups zusätzliche Pre-Main-Zeit (#35409).
Die HTTP-Durchsatzgewinne reiten auf einem neuen Deno-eigenen HTTP/1.1-Serving-Pfad, der den Hyper-basierten Pfad ablöst, den Deno seit 1.x ausliefert (#34446). Die beiden Rust-Ports sind kleiner, aber folgenreich: crypto.subtle (#34966) und console / Deno.inspect (#35087) wandern von JavaScript nach Rust und reduzieren den Per-Call-Overhead ohne Verhaltensänderung. Der WebCrypto-Port ist die Voraussetzung für die WebCrypto-Modern-Algorithms-Arbeit, die in derselben Release landet.
Die Speicher-Planheit unter Last ist die operativ wichtigste Änderung. In 2.8 wuchs die RSS mit der Last, von rund 94 MB beim Servieren von Plaintext bis zu 197 MB beim Streamen von 1-MiB-Bodies. In 2.9 bleibt sie im Wesentlichen flach, hält sich um 62 MB, unabhängig davon, was der Server tut. Das ergibt 2,2x weniger Spitzen-RSS bei der Realworld-Last und 3,1x weniger bei 1-MiB-Bodies, sodass dieselbe Maschine deutlich mehr gleichzeitige Deno.serve-Instanzen fahren kann, bevor ihr die Luft ausgeht. Das Team markiert das als das Highlight des Zyklus.
Supply-Chain-Härtung
Die zweite Schlagzeile ist die Supply-Chain-Härtung, und sie ist der Teil von 2.9, der sich am direktesten auf den Axios-npm-Supply-Chain-Angriff von März und den Red-Hat/Shai-Hulud-npm-Angriff von Anfang Juni abbilden lässt.
npm Minimum Release Age, standardmäßig aktiv. PR #35458 aktiviert das Minimum Release Age standardmäßig mit einem 24-Stunden-Fenster. Die Einstellung wurde in Deno 2.6 eingeführt und war bereits dokumentiert, aber in 2.9 ist sie standardmäßig an. Das Prinzip ist einfach: Eine große Klasse von npm-Supply-Chain-Angriffen lässt sich durch Abwarten abfangen, weil eine bösartige Version meist innerhalb von ein bis zwei Tagen nach ihrer Veröffentlichung erkannt und wieder entfernt wird; ein 24-Stunden-Fenster weist die meisten davon beim Install zurück. Die Vorgabe sitzt am unteren Ende der Präzedenzkette, sodass alles, was Sie explizit in .npmrc setzen, gewinnt: min-release-age=72h verlängert das Fenster, min-release-age=0 deaktiviert vollständig. Dies ist dieselbe Verteidigung, die pnpm in 9.x und Bun in 1.x auslieferten. Deno ist der dritte große Paketmanager, der sie standardmäßig aktiviert.
No-Downgrade Trust Policy, opt-in. PR #34927 ergänzt die Trust Policy, die Deno bisher fehlte. Sie reiht ein, wie jede Paketversion veröffentlicht wurde, in dieser absteigenden Reihenfolge der Stärke: Staged Publishing (ein Maintainer, der mit einer Live-2FA-Challenge freigibt), Trusted Publishing mit Provenance-Attestation, eine alleinstehende Provenance-Attestation und zuletzt eine einfache Token-Veröffentlichung. Mit trust-policy=no-downgrade in .npmrc weigert sich Deno, eine Version aufzulösen, deren Vertrauensbeweis schwächer ist als der stärkste Beweis einer zuvor veröffentlichten Version desselben Pakets, verglichen nach Veröffentlichungsdatum. Wenn ein Paket konsistent über Trusted Publishing oder mit Provenance ausgeliefert wurde und plötzlich eine spätere Version als einfache Token-Veröffentlichung erscheint (das Kennzeichen eines kompromittierten Maintainer-Tokens, wie beim s1ngularity-Vorfall im August 2025, der sich in den Axios-npm-Supply-Chain-Angriff und den Red-Hat/Shai-Hulud-npm-Angriff verlängerte), wird die Installation zu einem harten Fehler statt zu einem stillen Downgrade. Die Policy folgt pnpm's Design, und Deno liefert zwei Hintertürchen, die pnpm spiegeln: trust-policy-ignore-after (in Minuten) überspringt die Prüfung für ältere, tatsächlich pre-Provenance-Veröffentlichungen, und trust-policy-exclude[]=package befreit benannte Pakete. Die Policy ist standardmäßig aus, weil Provenance und Trusted Publishing auf dem Registry weiterhin ungleichmäßig angenommen sind.
Lockfile-Interop. Die Supply-Chain-Geschichte erstreckt sich auf Lockfiles. Beim ersten deno install in einem Projekt, das ein package-lock.json, pnpm-lock.yaml, yarn.lock oder bun.lock, aber kein deno.lock hat, seedet Deno einen frischen deno.lock direkt daraus und übernimmt die exakten aufgelösten Versionen und Integritäts-Hashes (#34296, #35330, #35346, #35350, #35394). Für pnpm-Workspaces wird die separate pnpm-workspace.yaml automatisch nach package.json (oder deno.json) migriert, ohne Kommentare oder bestehende Felder zu stören (#34993). Für eine deno.lock, die bereits Git-Merge-Konflikt-Marker aus einem verpatzten Rebase enthält, löst Deno sie nun automatisch auf, vereinigt die additiven Sektionen und nimmt bei echten Spezifizierer-Konflikten die höhere Version (#34726). Zusammengenommen bedeutet das, dass das Umschalten eines Node-Projekts auf Deno nur wenige Befehle braucht und den bestehenden Abhängigkeitsgraph exakt bewahrt.
Test-Runner-Parität mit Vitest / Jest
Die Test-Runner-Arbeit schließt die Vitest-/Jest-Funktionslücke, die der meistgenannte Grund für Teams war, die an einem Node-gehosteten Testframework festhalten, selbst wenn sie Deno für Produktionscode mögen.
Eingebaute Snapshot-Tests. PR #35139 ergänzt t.assertSnapshot() im Testkontext, im selben Format und Serializer wie @std/testing/snapshot, ohne Import erforderlich. Snapshots werden in __snapshots__/test_file.snap neben dem Test geschrieben; bei einem Mismatch druckt der Runner einen Diff und sagt, wie man aktualisiert (deno test --update-snapshots). Snapshots am Standardort brauchen keine read/write-Permissions (der Runner verwaltet sie), und veraltete Einträge werden automatisch entfernt, wenn ein vollständiger Lauf sie aktualisiert. Snapshot-Testing funktioniert auch über node:test, via t.assert.fileSnapshot() (#35478).
Deno.test.each. PR #34938 registriert einen unabhängig filterbaren Test pro Input-Zeile. Array-Cases werden als positionale Argumente gespreizt; Objekt-Cases werden als einzelnes Argument übergeben und können über $key in den Testnamen interpoliert werden. Namens-Templates unterstützen Printf-artige Tokens (%s, %i/%d, %f, %j, %o), %# für den Case-Index und $key.nested für verschachtelten Objekt-Zugriff. Deno.test.only.each und Deno.test.ignore.each komponieren sich wie erwartet.
deno test --shard. PR #35057 teilt die entdeckten Testdateien für CI-Fan-out in balancierte Gruppen auf. Es fällt direkt in eine GitHub-Actions-Matrix; der Index ist 1-basiert, Sharding passiert vor --shuffle, und Over-Sharding (mehr Shards als Dateien) lässt einfach manche Shards leer und beendet sauber. Der Trade-off, den die PR explizit benennt: Der Shard wird zur Laufzeit ausgewählt, nachdem der Modulgraph für die gesamte Suite gebaut und type-checked wurde, sodass jede Maschine weiterhin die Graph-Build- und Type-Check-Kosten für die ganze Suite zahlt. Den Shard-Vorfilter vor das Type-Checking zu verschieben, ist ein natürliches Follow-up.
Retry und Repeats. PR #35053 ergänzt die Optionen retry: N und repeats: N, entweder pro Test oder über den ganzen Lauf. Ein Test, der erst nach einem Retry besteht, wird im Summary als flaky gemeldet, damit das Signal nicht still verloren geht. Per-Test-Optionen haben Vorrang vor den CLI-Flags (inklusive einer expliziten 0, um einen Test zu deaktivieren).
Change-Aware-Testauswahl. PR #35199 ergänzt deno test --changed (Tests, die von nicht committeten Änderungen betroffen sind), deno test --changed=origin/main (Tests, die seit dem Abzweigen von main betroffen sind) und deno test --related=src/util.ts (Tests, die von einer bestimmten Datei abhängen). Die Auswahl ist Dependency-Aware (sie traversiert den Modulgraph über Workspace-Mitglieder hinweg) und konservativ: Eine Änderung an Config, Lockfile, Import-Map oder package.json deaktiviert das Filtern und führt alles aus.
Coverage-Thresholds. PR #35056 lässt Coverage einen Lauf fehlschlagen lassen, wenn sie unter ein Ziel fällt, entweder per --threshold=90 oder pro Metrik in deno.json konfiguriert (lines, branches, functions). Wenn das Aggregat zu kurz fällt, beendet der Befehl mit Exit-Code ungleich null und sagt, welche Metrik verfehlt wurde.
deno desktop erscheint im ersten getaggten Build
Der deno-desktop-Subcommand, der als PR #33441 am 16. Juni merged wurde, erscheint in Deno 2.9 als erstes getaggtes Build mit dem Feature. Der Artikel vom 16. Juni deckt den Architekturteil ab (WEF-Backend, CEF als Default, Webview-/Raw-Alternativen, Deno.BrowserWindow-API, Framework-Auto-Erkennung für Next.js / Astro / Fresh / Remix / Nuxt / SvelteKit / SolidStart / TanStack Start / Vite SSR, CDP-Multiplexer für vereinheitlichte DevTools über zwei V8-Isolates, Auto-Updater mit bsdiff-Patches, Cross-Compile). Das 2.9-Release fügt die praktischen Teile hinzu, die aus der PR etwas Versandfertiges machen:
- Default-UI-Backend ist webview (#35442), damit Binaries klein bleiben und schnell starten.
--backend cefwechselt zu gebündeltem Chromium für garantiert identisches Rendering auf jeder Plattform. - Natives Wayland statt XWayland auf Wayland-Systemen (#35485). Die PR vom 16. Juni war nur X11-fähig und ließ Wayland-Sessions über XWayland laufen; der 2.9-Zyklus hebt diese Einschränkung auf.
- Linux-.deb- und .rpm-Installer-Ausgabeformate (#35296), erzeugt von jedem Host ohne plattformspezifische Packaging-Toolchain.
- Windows-.msi-Installer-Ausgabeformat (#35378), ebenso.
- Auto-Erkennung des Vite-Frameworks (#35470), zusätzlich zur Liste Next / Astro / Fresh / Remix / Nuxt / SvelteKit / SolidStart / TanStack Start.
- Bluetooth-Nutzungsbeschreibungen und macOS-Desktop-Info.plist-Schlüssel (#35472, #35484), für die Bereitschaft zur App-Store-Einreichung.
- Gebündelte libc++-Symbole maskiert (#35424), damit die Desktop-Runtime auf Linux dlopen-bar ist.
- --compress für selbstextrahierende App-Bundles (#35420), die sich beim ersten Start entpacken und die Artefaktgröße für npm-schwere Projekte reduzieren.
Das vollständige Handbuch liegt unter docs.deno.com/runtime/manual/desktop, und denidian, eine mit deno desktop gebaute Notiz-App, wird daneben als Referenzbeispiel veröffentlicht.
WebCrypto Modern Algorithms
Die WebCrypto-Arbeit ist derselben Familie wie der Node.js 24.18.0 'Krypton' LTS Web Crypto-Artikel und die Node.js 26.4.0 'Current' WebCrypto-cSHAKE-Arbeit: der Modern Algorithms in the Web Cryptography API-Vorschlag, beginnend mit den Post-Quantum-Algorithmen des NIST.
- ML-KEM (FIPS 203) Key Encapsulation: ML-KEM-512, ML-KEM-768, ML-KEM-1024 (#34447). Ergänzt vier neue
crypto.subtle-Methoden:encapsulateKey/encapsulateBitsunddecapsulateKey/decapsulateBits. - ML-DSA (FIPS 204) Signaturen: ML-DSA-44, ML-DSA-65, ML-DSA-87, inklusive JWK-Import/Export (#34448, #34914).
- SLH-DSA (FIPS 205) Signaturen, alle zwölf Parametersätze (#35223).
- ChaCha20-Poly1305 AEAD (#34417).
- SHA-3-Familie und XOFs: SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256, cSHAKE, TurboSHAKE, KangarooTwelve.
- KMAC und Argon2-Key-Derivation.
Eine neue synchrone Feature-Detection-Methode SubtleCrypto.supports() (#34903) erlaubt es Anwender-Code, den Support zur Laufzeit zu prüfen: SubtleCrypto.supports("sign", "ML-DSA-65") liefert true auf einem 2.9-Build. Die gesamte crypto.subtle-Implementierung wurde von JavaScript nach Rust portiert (#34966), was den Per-Call-Overhead reduziert, ohne das Verhalten zu ändern, und was die Voraussetzung dafür ist, dass die Post-Quantum-Arbeit in derselben Release landet.
Node.js-Kompatibilität zieht auf 26 vor
Deno 2.9 verschiebt sein Node.js-Kompatibilitätsziel auf Node 26. Die gemeldete process.version bewegt sich auf v26.3.0 (#34747), und die node-compat-Testsuite, die Deno ausführt, steigt auf 26.3.0 (#34746). Bare Node-Builtins lösen sich nun ohne Konfiguration auf: import fs und import path mappen bedingungslos auf node:fs / node:path, ohne --unstable-bare-node-builtins-Flag (#33316). Dies fixt auch einen Bug, bei dem ein node_modules-Paket einen Builtin shadowen konnte; Builtins gewinnen nun immer, während deno.json-Imports und package.json-Dependency-Mappings ihre Präzedenz behalten.
Die node:test-Zugewinne sind für sich genommen ein wichtiges Stück: mock.module() und mock.timers (#35329, #33946), t.assert.fileSnapshot() (#35478) und TestContext.runOnly() (#35158). Der Runner schlägt nun bei unbehandelten Rejections fehl, erzwingt Timeouts und führt Hooks in der korrekten Reihenfolge aus (#35297, #35393). Weitere Runtime-APIs: process.resourceUsage() (#35468) und worker_threads.isInternalThread (#35234) sind nun implementiert, und AsyncLocalStorage-Context bleibt über node:net-Callbacks hinweg erhalten (#35237). Deno's NAPI-Implementierung meldet nun Version 10 (#35270), in Einklang mit Node 26. Die Web-Storage-/KV-Persistenz (#34618) für deno compile-Outputs und die preferPackageJson-Einstellung (#35392) sind dieselbe kompatibilitätsgetriebene Ergonomiearbeit, nun stabilisiert.
Lockfile-Interop und Abhängigkeitsverwaltung
Die Lockfile-Arbeit ist der Teil von 2.9, der am direktesten darauf abzielt, Node-Projekten den Wechsel zu Deno zu ermöglichen. Die fünf Lockfile-lesenden PRs (#34296, #35330, #35346, #35350, #35394) bedeuten zusammen, dass deno install in einem Projekt mit package-lock.json, pnpm-lock.yaml, yarn.lock oder bun.lock einen deno.lock erzeugt, der die exakten aufgelösten Versionen und Integritäts-Hashes aus dem bestehenden Lockfile bewahrt. Es gibt keine Neuauflösung und keine überraschenden Upgrades: Die Versionen, unter denen Sie unter npm liefen, sind die Versionen, unter denen Sie unter Deno laufen. Von da an schreibt deno install ein node_modules-Verzeichnis, das Deno ausführen kann, und deno task führt die package.json-Skripte aus, die Sie bereits haben, sodass der Rest des Teams weiterarbeiten kann wie bisher.
Für pnpm-Workspaces wird die separate pnpm-workspace.yaml automatisch nach package.json (oder deno.json) migriert, ohne Kommentare oder bestehende Felder zu stören (#34993). Kombiniert mit dem catalog:-Protokoll, das Deno in 2.8 einführte, funktionieren zentralisierte, geteilte Dependency-Versionen nach dem Wechsel weiter. Für deno.lock-Dateien, die bereits Git-Merge-Konflikt-Marker aus einem verpatzten Rebase enthalten, löst Deno sie nun automatisch auf, vereinigt die additiven Sektionen und nimmt bei echten Spezifizierer-Konflikten die höhere Version (#34726). Wenn ein node_modules-Verzeichnis in Gebrauch ist, installiert die neue opt-in-Einstellung jsrDepsInNodeModules jsr:-Abhängigkeiten über JSRs npm-Kompatibilitäts-Registry hinein (#35029), analog dazu, wie pnpm und npm bereits JSR-Pakete behandeln.
Die neuen Subcommands der Abhängigkeitsverwaltung runden das Bild ab. deno link und deno unlink (#34359) geben First-Class-CLI-Zugriff auf das links-Array in deno.json (den npm-Link-artigen Workflow für lokale JSR-Pakete). Das Feld links selbst ist in 2.9 stabil: Es wurde unter diesem Namen bereits in 2.3 ausgeliefert und war nie hinter einem Runtime-Flag verborgen, also lässt 2.9 einfach die verbliebene Unstable-Beschriftung fallen (#34996). deno list (#34972) druckt die Abhängigkeiten, die ein Projekt in deno.json und package.json deklariert, und löst ihre Versionen auf, das Äquivalent von npm ls / pnpm list. deno watch (#35301) ist ein kurzer, besser auffindbarer Alias für deno run --watch-hmr main.ts, der bei Dateiänderungen mit Hot Module Replacement neu ausführt und neu startet, falls Hot Replacement fehlschlägt.
deno fmt auf den lax-Engines
deno fmt wird auf den neuen lax-Formatierungs-Engines neu aufgebaut, die nur Whitespace verschieben: Sie ordnen nie um, requoten nie, lassen nie ein Token fallen und reichen fehlerhafte Eingaben durch statt zu erroren. HTML, XML und SVG werden nun von lax-markup formatiert, und sie werden standardmäßig ohne Flag formatiert (#35174). Komponentenformate (Vue, Svelte, Astro, Vento, Nunjucks, Mustache) sind unter --unstable-component verfügbar. Ein 10-MB-Dokument, das vorher in 15 Minuten nicht formatiert werden konnte, braucht nun etwa eine Zehntelsekunde. CSS, SCSS und Less werden nun von lax-css formatiert (weiterhin unter --unstable-css), was eine lange Liste von Parse-Fehlern und Value-Mangling-Bugs fixt (#35160). Beachten Sie, dass die eingerückte .sass-Syntax nicht mehr unterstützt wird. SQL-Formatierung (unter --unstable-sql) wird nun von lax-sql betrieben, das kanonische, dialektagnostische Ausgabe produziert (#35161).
Zwei neue Konfigurationsoptionen für JavaScript und JSON: sortNamedImports und sortNamedExports steuern, wie benannte Spezifizierer geordnet werden (caseInsensitive (Standard), caseSensitive, maintain (Quellreihenfolge belassen, praktisch, um Biome's Sortierung zu matchen)) (#33313); und json.trailingCommas steuert Trailing Commas in JSON und JSONC (never, always, maintain, jsonc) (#33383). deno fmt liest nun .editorconfig-Dateien und nutzt sie, um alle Formatierungsoptionen zu füllen, die der Anwender nicht explizit gesetzt hat, mit einer Präzedenz CLI-Flags → deno.json → .editorconfig → eingebaute Defaults (#34071).
deno task, deno compile, deno bundle
Der Taskrunner nimmt Input-basierten Cache, Concurrency-Steuerung und mehrere neue Flags auf. Input-basierter Cache: Deklarieren Sie die Inputs einer Task mit files (und Outputs mit output), und Deno überspringt die Task vollständig, wenn nichts Relevantes sich geändert hat, und restauriert alle deklarierten Output-Artefakte direkt aus dem Cache (#34509). Der Fingerabdruck enthält den Befehl, den Inhalt der durch files gematchten Dateien, die Werte aufgelisteter env-Variablen, die Fingerabdrücke der Abhängigkeiten der Task, das Host-OS, die CPU-Architektur und die Deno-Version. Argumente und env sind Teil des Schlüssels: deno task build foo und deno task build bar cachen unabhängig, und das Ändern eines gelisteten env-Werts invalidiert den Cache. Abhängigkeiten kaskadieren (eine Task läuft neu, wenn eine ihrer Abhängigkeiten neu lief, selbst wenn ihre eigenen Inputs unverändert sind). Sicher per Default: Wenn die Datei-Globs nichts matchen, wird die Task als nicht-cachebar behandelt und läuft immer; ein Tippfehler kann also nie einen falschen Cache-Hit erzeugen. npm-Skripte und Tasks ohne command werden nie gecacht.
Concurrency-Steuerung: --jobs (kurz -j, Alias --concurrency) begrenzt, wie viele Tasks in einem Workspace-Lauf gleichzeitig laufen; --jobs 1 erzwingt sequenzielle Ausführung; es überschreibt die DENO_JOBS-Umgebungsvariable und defaulted auf die Anzahl verfügbarer CPUs (#35318). Weitere Flags: --if-present beendet mit 0 statt zu erroren, wenn die benannte Task nicht existiert, passend zu npm (#35315); --env-file lädt eine dotenv-Datei in die Task-Umgebung, ohne das Flag an jeden inneren Befehl weiterzureichen (#34508); Ausschlussgruppen in Task-Namen-Wildcards (deno task test:*(!e2e|interactive)) führen jede test:*-Task außer den ausgeschlossenen aus (#34506).
deno compile erhält --include-as-is, das eine Datei oder ein Verzeichnis in das virtuelle Dateisystem der Executable einbettet, ohne Modulauflösung oder Transpilation (#32417). Wo --include Dateien durch den Modulgraph laufen lässt, ist --include-as-is für Assets und vorgefertigte Bundles gedacht, die Sie zur Laufzeit einfach per Filesystem-APIs verfügbar haben wollen. Die beiden Flags kombinieren, sodass Sie einige Module auflösen und andere verbatim in denselben Build einbetten können. Kompilierte Binaries erhalten auch echten persistenten Speicher: Ein Default-Deno.openKv(), localStorage und die caches-API persistieren nun in einem Per-App-Verzeichnis unter dem App-Data-Speicherort der Plattform statt auf In-Memory-Storage zurückzufallen (#34618). Die Speicheridentität ist das neue Flag --app-name, das standardmäßig auf den Namen der Ausgabedatei fällt; zwei Binaries, die mit demselben --app-name gebaut wurden, teilen sich einen Store, und das Umbenennen einer Binary verliert nicht mehr deren Daten. Per Default embeddet deno compile den gesamten aufgelösten node_modules-Baum in die Binary; das neue experimentelle Flag --bundle lässt stattdessen den Entrypoint zunächst durch Deno's Bundler laufen (Tree-Shaking und Emission eines einzelnen Moduls), was Binaries für npm-schwere Projekte dramatisch schrumpfen kann (ein lodash-Hello-World fiel in Deno's eigenen Messungen von 11,6 MB auf 1,5 MB). Kombinieren Sie mit --minify, um das eingebettete Bundle weiter zu verkleinern (#34527, #34532, #34536). deno compile nimmt auch einen --watch-Modus auf (#34860). deno bundle kann nun mit --declaration ein gerolltes .d.ts neben dem gebundelten JavaScript ausgeben (#33838) und versteht die Objektform von npms package.json browser-Feld beim Bundeln mit --platform browser (#34407).
Web-Platform- und Runtime-Ergänzungen
Sechs Ergänzungen der Web-Platform-Oberfläche erscheinen in 2.9. Die Web Locks API erscheint vollständig (#31166) und erlaubt die Koordination des Zugriffs auf eine benannte Ressource über async Tasks und Worker hinweg durch navigator.locks.request("config", async lock => { /* exklusiver Zugriff hier bis dieser Callback sich auflöst */ }), mit Shared-vs-Exclusive-Modi, ifAvailable, steal, einem AbortSignal und navigator.locks.query() zur Inspektion gehaltener und ausstehender Locks. Happy Eyeballs v2 (RFC 8305) landet in Deno.connect und Deno.connectTls (#31726) und lässt IPv6- und IPv4-Adressen auf Dual-Stack-Netzwerken um die schnellere, zuverlässigere Verbindung konkurrieren, standardmäßig aktiv mit autoSelectFamily: false zum Abschalten. navigator.userAgentData erscheint in Window- und Worker-Scopes (#34743). RequestInit akzeptiert das Fetch-Standard-priority-Member (auto, high, low) (#34716). Deno.watchFs unterstützt eine ignore-Option für Pfade wie .git oder build-Output (#31582). process.kill auf den eigenen Prozess verlangt kein --allow-run mehr (#34382).
CSS-Modul-Importe erscheinen unter --unstable-raw-imports (#35093), passend zum CSS module scripts Web-Standard: import sheet from "./styles.css" with { type: "css" }; liefert eine CSSStyleSheet-Instanz, sodass derselbe Code in Deno und im Browser ohne Bundler-Schritt läuft. Stabiles --unsafe-proto (#34738, #35192) ersetzt das unstable Flag, und wenn ein Programm nach Berührung des deaktivierten Object.prototype.__proto__-Accessors crasht, schlägt Deno vor, es damit neu zu starten. Der WebAssembly-ESM-Integration-Fix (#34912) entpackt globale Exports aus importierten .wasm-Modulen, passend zur WebAssembly/ESM-Spec und Node. Deno.serve komprimiert Antwort-Bodies nicht mehr automatisch (#35253, #35486); aktivieren Sie es pro Server mit automaticCompression: true oder prozessweit mit DENO_SERVE_AUTOMATIC_COMPRESSION=1. OpenTelemetry erhält OTEL_TRACES_SAMPLER (mit OTEL_TRACES_SAMPLER_ARG) für Head-Based Sampling, OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT und OTEL_SPAN_EVENT_COUNT_LIMIT für Per-Span-Caps und Auto-Instrumentation, die nun auch node:http2-Clients und -Server tracen (#34764, #34787, #34795, #34510).
Was dieses Release mit Deno's Trajektorie macht
Der 2.9-Zyklus ist das erste Mal, dass Deno drei ungefähr gleichwertige Schlagzeilenkategorien in einem einzigen getaggten Build ausliefert: einen großen Perf-Sprung (Cold Start, Speicher, Durchsatz), eine große Supply-Chain-Härtung (Minimum Release Age standardmäßig an, opt-in No-Downgrade Trust Policy) und eine große Feature-Lieferung für den Test-Runner (Snapshot-Tests, parametrisierte Tests, Sharding, Retries, Change-Aware-Auswahl, Coverage-Thresholds). Der Desktop-Subcommand, der als PR #33441 am 16. Juni merged wurde, erscheint endlich als erstes getaggtes Build; die Lockfile-Interop-Arbeit bedeutet, dass ein Node-Projekt mit wenigen Befehlen und bewahrtem Abhängigkeitsgraph zu Deno wechseln kann, und die WebCrypto-Modern-Algorithms-Arbeit bringt Deno auf dieselbe Post-Quantum-Kryptografie-Schiene wie Node 24 LTS und Node 26 Current.
Die Teile, die das Team als nächste Deno-Release-Kandidaten markiert hat, sind aus den PR-Beschreibungen ablesbar: Sharding vor dem Type-Check (der Trade-off der #35057), Erweiterung der Web Locks API (Timeouts, steal mit Timeout), die No-Downgrade Trust Policy mit Per-Paket-Overrides jenseits des bestehenden trust-policy-exclude[]-Arrays, und deno fmt, das die lax-Engines von unstable zu stable befördert. Die vollständige Liste der 165+ PRs im 2.9-Zyklus steht auf der Deno 2.9.0 GitHub-Release.



