✨ Highlights
Experimental tracing channels. Nitro now has built-in tracing channel support for tracing request spans.
Smarter dependency tracing. traceDeps picks up full-trace mode and custom trace options, backed by upstream nf3 improvements — a growing native-packages DB and automatic detection of optional dependencies mean fewer missing binaries in production bundles.
H3 v2 updates Stricter streaming body-size checks, cookie utils with RFC 6265bis compliance, and a handful of request normalization fixes — including protection against path traversal via double-encoded segments.
Ecosystem upgrades. ocache now has cache invalidation via handler.invalidate() and multi-tier cache support, and unstorage now proactively flushes expired memory entries instead of waiting for the next access both available for Nitro cache and KV storage.
Vercel preset supports queues and per-route function config. You can now use Vercel queues in Nitro deployments to process messages asynchronously (docs), and override function config on a per-route basis(#4124) handy when a single route needs more memory or a longer timeout than the rest of your app.
Deploy to Tencent EdgeOne Pages. Deploy Nitro apps to EdgeOne Pages (docs)
OpenAPI and WebSocket docs. New guides for OpenAPI and WebSocket.
🚀 Enhancements
- vercel: Allow overriding function config per route (#4124)
- traceDeps: Support full-trace and custom trace options (#4175)
- Add version meta to Nitro instance (#4193)
- openapi: Add swagger ui config (#4185)
- vercel: Support queues (#4127)
- Experimental built-in tracing channel support (#4001)
- Add
edgeone-pagespreset with build output api v3 (#4170) (docs)
🩹 Fixes
- cloudflare-dev: Match
getPlatformProxydev behaviour with production runtime (#4102) - Use
rolldown/utilsand disable additionaltsconfigparsing (#4111) - route-meta: Unique handlers by hash + method + route (#4119)
- route-meta: Deduplicate routing-meta imports by
_importHashonly (#4120) - Guard against
createRequire(import.meta.url)in bundled output (#4133) - cloudflare: Set rolldown platform to
nodewhennodeCompatis active (#4138) - cloudflare: Add
workerto default conditions (9054dee6) - vite: Match service entry chunk by
facadeModuleId(#4123) - vite: Handle dotted Nitro routes under baseURL in dev (#4108)
- vite: Proxy
nitro/*imports from service environments (#4152) - runtime: Avoid infinite recursion in fetch for external URLs (#4153)
- build: ⚠️ Remove custom moduleSideEffects config (#4164)
- config: Treat
swr: 0as a valid cache value (#4167) - Exclude wrangler from generated
NitroRuntimeConfigtype (#4149) - Allow to run tasks via nitro cli (#4188)
- deno-deploy: Add
req.ip(#4196) - Always run
basicAuthroute rule first (#4204)
💅 Refactors
📖 Documentation
- Correct routing example code (#3937)
- Fix typos (#4169)
- Remove import in auto-imports example (#4150)
- Use cleaner imports in examples and add read more links to config (#4200)
- Add openapi guide (#4198)
- Add websocket guide (#4197)
📦 Build
- Move docs to dist/docs (9ce219ca)
Preset Changes
- vercel: Support max value on maxDuration types (#4172)
⚠️ Breaking Changes
- build: ⚠️ Remove custom
moduleSideEffectsconfig (#4164)
🌱 Ecosystem
Notable upstream changes rolled in via dependency updates:
h3 rc.16 → rc.20
- Add
redirectBackutility (#1329) - cors: Preserve CORS headers on error responses (#1352)
- sse: Mark writer as closed on write failure (#1322); sanitize carriage returns in event stream (79cabe3)
- request: Include
Allowheader in 405 response (#1314) - mount: Normalize percent-encoded pathname in
requestWithBaseURL(0295f90); enforce path segment boundary instartsWith(7ccc9e2) - static: Prevent path traversal via double-encoded dot segments (8e9993f)
- utils: Prevent open redirect via protocol-relative path in
redirectBack()(459a1c6) - cookie: Prevent unbounded chunked cookie count (399257c)
- body: Enforce stream-based body size check regardless of content-length (708a3aa)
- Upgrade
cookie-esto v3 (9d244a7)
crossws 0.4.5
WebSocket Proxy integration will be added as a nitro route rule in next releases. You can directly use it in meanwhile from crossws package.
- New
createWebSocketProxyutil (#184) - New
fromNodeUpgradeHandlerutil +socket.iosupport (#185) - New
bunnyadapter (#179) - node: Do not url-encode upgrade response headers (ffbed40)
srvx 0.11.9 → 0.11.15
- node: Handle error and abort propagation for piped streams (77f879b)
- node: Fallback to socket address on invalid Host header (#192)
- node: Combine duplicate headers in
entries()iterator (4ed7453) - node: Improve
pipeBodystability and performance (5e731ef, 4051f22) - url: Deopt absolute URIs in FastURL (de0d699)
- node: Handle
EADDRINUSEport conflict on serve (#197) - node/web: Do not swallow
getReadererrors (#199)
unstorage 2.0.0-alpha.7
- memory: Proactively flush expired entries after ttl (#759)
- fs: Resolve ignore pattern matching for dot-prefix paths (#751)
ocache 0.1.2 → 0.1.4
- Respect
staleMaxAge(8915db3) and zero ttl (#5) - cache: Add
resolveCacheKeyand.resolveKey()(#6) - storage: Nullish
setdeletes entry (71d5f11) - Multi-tier cache base (#7)
- cache: Add
handler.invalidate()(#8); evict stale entry on SWR revalidation failure (#9) - storage: Proactively flush expired memory entries (#10)
- cache: Skip writing to lower tiers on multi-tier cache hit (4fe0de7)
nf3 0.3.11 → 0.3.16
- Add
fullTraceIncludeoption (#4) - plugin: Use
traceInclude(#27) - trace: Avoid shared reference mutation in applyProductionCondition (fb3eac2); improve multi-version hoisting (328dbc1)
- Expand native packages DB (#31, 82ed28d)
- trace: Auto-detect and copy
optionalDependencies(#35) - trace: Add
FullTracePackagesdb (#36) - trace: Auto-include
.nodebinaries for native packages (1aa42c8)
env-runner 0.1.7
- Support custom export conditions (#5)
- vercel: Add vercel runner (#3); shim
@vercel/request-contextfor@vercel/functionscompat (cb9a358) - Netlify runner (7e47106)
- miniflare: Pass through
cloudflare:*imports to workerd (#6) - deno: Use stdin/stdout IPC and prevent
deno.lockcreation (1df4340)
hookable 6.0.1 → 6.1.1
❤️ Contributors
- Pooya Parsa (@pi0)
- Venzil (@q153877011)
- Rihan Arfan (@RihanArfan)
- Huseeiin (@huseeiin)
- Jordan Kniest (@jkniest)
- Oskar Lebuda (@OskarLebuda)
- Johann Schopplich (@johannschopplich)
- Vishnu Kasireddy (@VISHNU7KASIREDDY)
- Manuel Schiller (@schiller-manuel)
- Daniel Roe (@danielroe)
- Jakob Malmo (@jmalmo)
- Kricsleo (@kricsleo)
- Kendell (@KTibow)
- Roman (@gameroman)
- Vamsik
- Clay