🚀 Enhancements
- scan: Support
QUERYmethod suffix for file-based routes (#4594) - builder: Expose
startPreviewanddeploy(#4619) - Pass server entry options to
srvx(#4620) - vite: Add
vite:compile:beforehook (#4440) - dev: Minimal error page (#4699)
- Experimental
builder: false(#4686) - cache: Decouple cache storage from kv with
cacheconfig (#4709) - Install
unenvon demand (#4710) - Add unified
buildPluginsoption (#4715) - dev: Serve chrome
devtools.jsonfor automatic workspace folders (#4747) - vite: Vitest support (#4748)
- config: Expose resolved config layers as
nitro.options.layers(#4813) - Respond with 405 for routes matched only by other methods (#4811)
- vite: ⚠️ Move
experimental.viteoptions toviteconfig (#4827) - dev: Use runtime-native server for dev listener (#4832)
- Install
unstorage,db0andocacheon demand (#4764) - runtime: Support async plugins (#4840)
- scan: ⚠️ Reserve dotted suffixes in scanned file names (#4845)
- On-demand dependency manifest and
depsoption (#4839) - cli: Add
nitro serve(#4849) - cli: Add
nitro createcommand (#4878) - Resolve tsconfig
pathsaliases with all builders (#4879) - tracing: Trace
db0queries (#4909) - Enable
srvxFastResponseglobally for node builds (#4910) - prerender: Add
ignoreStatusCodesoption (#4922) - dev: Add
devServer.drainoption (#4916) - Emit files referenced with
new URL(..., import.meta.url)(#4932) - Add
import.meta.envNameand--envNamecli flag (#4934) - cli: Add
nitro fetchcommand (#4958) - prerender: Support
rou3patterns inprerender.ignore(#4961)
🔥 Performance
- runtime: Skip static middleware work for non-asset requests (#4854)
- unbundled: Synchronous built-in plugin hooks (#4862)
- cli: Run
nitro servein-process withoutbuildPlugins(#4865) - build: Skip gzip for
node_modulesfiles in the size report (#4926) - build: Skip unchanged sourcemaps (#4925)
- build: Add a
codehook filter to the replace plugin (#4946)
🩹 Fixes
- static: Respond with 404 when a public asset is missing on disk (#4588)
- Resolve driver lib deps from the project only (#4589)
- vite: Run
closehooks when the dev server shuts down (#4593) - dev: Degrade gracefully when reaching system file watcher limit (#4616)
- config: Load
.envfiles when resolving non-dev config (#4607) - scan: Only auto-register
modules/*andmodules/*/indexfiles (#4595) - externals: Trace deps required from bundled commonjs packages (#4598)
- routing: Normalize route patterns like
h3(#4600) - vite: Start dev runner lazily and harden dev server routing (#4633)
- vite: Allow providing the vite package path (#4637)
- vite: Skip websocket upgrade listener in middleware mode (#4647)
- Only pass known safe server entry options to
srvx(#4654) - vite: Throw a descriptive error when a service entry has no
fetchhandler (#4656) - runtime: Use
node:pathin dev error handler (db7a719c) - vite: Pass renderer template path to
transformIndexHtml(#4672) - dev: Read renderer template on host when the runner has no fs access (#4676)
- build: Ignore
MODULE_LEVEL_DIRECTIVEwarnings (#4696) - vite: Wait for environment registration before dispatching dev requests (#4703)
- dev: Show cwd-relative paths in the error page on Windows (#4705)
- vite: Ignore errors after client disconnect (#4708)
- dev: Use the websocket adapter of the runtime the dev worker runs in (#4711)
- build: Reject output cleanup that deletes public assets (#4685)
- tasks: Stop scheduled tasks on runtime close (#4416)
- build: Select Nitro server entry from multiple chunks (#4668)
- dev: Proxy websocket upgrades for
devProxyroutes withws(#4480) - build: Set
debugNamefor rolldown lib chunks group (#4729) - vite: Route dev handlers + proxies before vite base rewrite (#4734)
- prerender: Only refuse
..as a whole path segment (#4738) - vite: Keep no-fallthrough public dir base and HEAD in sync with dev app routes (#4737)
- externals: Keep per-version ids for traced externals imported from bundled code (#4740)
- vite: Register service environments only after they are constructed (#4743)
- vite: Wait longer for slow dev reloads and add
NITRO_DEV_RELOAD_TIMEOUT(#4745) - externals: Externalize a package's own entry as its bare name (#4683)
- externals: Normalize bare package name on windows (9ca3af06)
- static: Handle weighted accept-encoding values (#4470)
- vite: Suppress aborted errors on HTTP/2 client disconnect (#4773)
- vite: Exclude virtual modules from vitest fs module cache (bf4a8287)
- config: Merge preset and user hooks instead of overriding (#4809)
- routing: Match base path for named catch-all routes (#4812)
- runtime: Serve HEAD requests with GET routes (#4817)
- cli: Avoid double prerender with vite builder (#4833)
- build: Compress late-written public assets (#4818)
- Run
closehooks once per nitro instance (#4835) - dev: Warn instead of failing when
nitro devdetects a vite config (#4850) - deps: Do not auto-install dependencies inside
node_modules(#4867) - vite: Guard against builtin aliases leaking into client build (#4864)
- vite: Allow importing
.svgfiles as text and bytes in dev (#4869) - Run middleware before the
cacheroute rule and keep middleware headers out of cache entries (#4873) - prerender: Follow route headers on non-HTML responses (#4842)
- vite: Support bundled dev client and renderer html (#4758)
- serve: Respect
listen.port: 0in unbundled server (8cd5f87a) - vite: Serve
?url-imported files from the project root in dev (#4781) - vite: Ignore falsy assets plugin entries (#4885)
- vite: Apply inline plugin options to provided nitro instance (#4881)
- vite: Use the running
vitein thenitro/viteplugin (#4883) - vite: Resolve
rolldownthrough the runningvitefor prerender and oxc (#4887) - config: Apply env-specific keys in config overrides (#4888)
- prerender: Strip
baseURLfrom crawled links (#4688) - prerender: Fail the build when prerendering writes nothing (#4674)
- vite: Only skip
vite-*WebSocket upgrades destined for Vite's HMR base (#4291) - Respect compress settings in dev server (#4159)
- vite: Bundle externals required from cjs in service environments (#4889)
- vite: Dispatch asset requests to config-registered catch-alls in dev (#4890)
- runtime: Apply
event.res.errHeadersto default error responses (#4891) - task: Add request timeout to
devFetchso a stalled dev server rejects instead of hanging (#4345) - prerender: Don't overwrite a route's output with different contents from another route (#4491)
- Nitro self-resolution, package manager fallback and bun dev aliases (#4892)
- unbundled: Bun alias rewrite follow-ups (#4893)
- prerender: Detect output collisions on case-insensitive filesystems (#4895)
- runtime: Don't cache missing static asset 404s (#4896)
- dev: Resolve public assets for internal fetch (#4894)
- runtime: Don't cache missing asset 404s on presets with
serveStatic: false(#4898) - vite: Scope nitro self aliases to the nitro environment (#4899)
- prerender: Wait for the prerender worker to be ready before crawling (#4902)
- routing: Normalize late-registered windows handler paths (#4908)
FastResponsefollow-ups (#4911)- deps: Install on-demand dependencies with non-production
NODE_ENV(0a2df9f8) - vite: Emit
srvxtracing channels in dev (#4924) - vite: Externalize dependencies with the
miniflarerunner (#4941) - rolldown: Externalize builtins aliased to
node:ids with that id (#4949) - rolldown: Turn
require()of builtins into esm imports on non-node platforms (#4953) - vite: Scope conflicting nitro aliases to the nitro environment (#4956)
- cli: Improve
nitro createfor agents (#4957) - Make server entry
fetchhandler optional (#4959)
🧩 Presets
Cloudflare
- Durable Objects, Workflows and RPC Service Bindings in dev (#4677)
- Merge
cloudflare_durableintocloudflare_module(#4846) - Guard
nodejs_compatflag by compatibility date (#4653) - Do not let browsers cache a 404 from public assets (#4727)
- Warn only about conflicting asset overrides (#4805)
- Write
_headersand_redirectsto the assets root (#4914) - Use module types for the module handler (d3dd0ace)
- ⚠️ Remove deprecated
eventfrom email and queue hooks (#4823) - Expose bindings in dev requests (#4608)
Vercel
- ⚠️ Remove
future.nativeSWRand legacy swr to isr mapping (#4826) - Fall back to request query when ISR header lacks the route param (#4599)
- Mark header-only route entries as
continue(#4652) - Skip ISR routes in observability routes (#4716)
- Keep
redirect: falsepaths out of broader redirects (#4728) - Enable ISR
passQuerywhenallowQueryis set (#4792) - Resolve function runtime from
package.jsonengines (#4768) - Keep edge routing for headers rules with
redirect: false(#4820) - Treat
*routes as catch-all in function paths (#4884) - Use
rou3pattern utils for route config (#4698) - Attach
waitUntilin node entry (#4579)
Netlify
- ⚠️ Emit output to frameworks api
.netlify/v1paths (#4829) - Use
denoexport condition (#4680) - Move publish files to root when
publicDirhas a trailing/(#4913) - Clarify 307/308 redirect downgrade limitation (#4726)
Azure
- ⚠️ Use azure functions v4 programming model by default (#4717)
- Prevent
azure-swaruntime errors, and response body returning{}(#4195)
AWS Amplify
- Default to
nodejs22.xruntime (#4824)
Node.js
- Support listening on unix socket via
NITRO_UNIX_SOCKET(#4814) - Respect container cpu limits for default worker count (#4784)
- Forward shutdown signals to workers (#4724)
Upsun
- Rename
platform-shpreset toupsun(206f243c)
Removed presets
- ⚠️ Remove
deno_deploypreset in favor ofdeno_server(#4841) - ⚠️ Remove
winterjsanddeno-deploypresets (#4857)
Multiple presets
- ⚠️ Drop compatibility date gates for cloudflare dev and vercel observability (#4828)
- Use
rou3for netlify, cloudflare and edgeone route patterns (#4706) - ⚠️ Do not prefix
baseURLon cloudflare pages and edgeone redirect targets (#4844) - Handle method-scoped route rules in platform configs (#4848)
- Skip route rules that netlify and cloudflare cannot express (#4804)
💅 Refactors
- Rename storage APIs to kv (
useKV,nitro/kv,kvconfig) (#4657) - Upgrade
h3to^2.0.1-rc.33androu3to^1.0.0(dce2c959) - Decouple config surface from
unenv(#4702) - build: Fall back to
oxboxwhenrolldownis not resolvable (#4712) - Make
rolldownan on-demand dependency (#4714) - vite: Use
NitroDevApproutes to route dev requests before vite (#4736) - runtime: Hide
routeRuleMiddlewarefromgetRouteRulestype (#4830) - ⚠️ Hide internal paths and dev server class from public API (#4831)
- ⚠️ Rename
rollup:before/rollup:reloadhooks to builder-neutral names (#4825) - ⚠️ Remove deprecated and unused options before rc (#4837)
- Make
ocachea regular dependency (f7a5c9a3) - ⚠️ Remove deprecated v3 beta aliases (#4960)
📖 Documentation
- examples: Use
relinstead oftypefor modulepreload links (#4585) - Clarify prerender and isr route rules (#4461)
- Improve grammar and wording in guide/tasks (#3433)
- Clarify
noExternalspath patterns (#4460) - vercel: Note cron endpoint is unauthenticated without
CRON_SECRET(#4596) - Document server entry startup logic (#4627)
- Use correct redirect signature (#4722)
- Fix stale firebase config section and blog anchor (#4760)
- Improvements (#4753)
- routing: Document named catch-all behavior change (#4815)
- bun: Document runtime environment variables and unix socket listening (#4870)
- websocket: Document subprotocol negotiation (#4843)
- github-pages: Update deploy workflow to current action versions (#4871)
- Split config reference into multiple pages (#4952)
- routing: Clarify route rules and middleware are not a security boundary (#4954)
📦 Build
- Bundle runtime entries and drop traced
node_modules(#4701) - Minify libs (f1e46f0a)
- Bundle
consola(256ce731) - Stop bundling docs in package (#4836)
- Externalize
rou3dependency (b46d994c) - Bundle
nf3dependency (7f7a778f)
🌊 Types
- Reject non-serializable storage and database options (#4590)
- Inline bundler, cloudflare and vercel queue types (1803dbcb)
- Remove unused types (2d2b72e0)
- Use optional dependency types when installed (ccf4db07)
- Consistent names for kv, cache, tracing and vite service types (#4741)
🏡 Chore
- examples: Add
vite-ssr-react-routerexample (#4403) - examples: Implement solid example (#4106)
- Update
h3to v2 (a136558c) - Mark
defineNitroConfigandCacheOptionsas deprecated (#4838) - ⚠️ Require Node.js
>=22.22.0(f9894e92, 7c6b29b8)
✅ Tests
- Isolate default sqlite database (22b17bb3)
- Remove unused
ts-expect-errortests (#4675) - Use
concurrent: falseinstead of removedsequentialoption (vitest 5) (db7847b6) - Clean up vite rebuild dist (#4746)
- serve: Cover ignored public files without a base url (#4860)
- Run presets suite with vite builder in ci (b2437562)
- Run tests on bun runtime (#4940)
- Cover middleware for non-GET requests to cached routes (e14b3c61)
⚠️ Breaking Changes
- azure: ⚠️ Use azure functions v4 programming model by default (#4717)
- presets: ⚠️ Drop compatibility date gates for cloudflare dev and vercel observability (#4828)
- vercel: ⚠️ Remove
future.nativeSWRand legacy swr to isr mapping (#4826) - vite: ⚠️ Move
experimental.viteoptions toviteconfig (#4827) - netlify: ⚠️ Emit output to frameworks api
.netlify/v1paths (#4829) - scan: ⚠️ Reserve dotted suffixes in scanned file names (#4845)
- presets: ⚠️ Do not prefix
baseURLon cloudflare pages and edgeone redirect targets (#4844) - cloudflare: ⚠️ Remove deprecated
eventfrom email and queue hooks (#4823) - ⚠️ Hide internal paths and dev server class from public API (#4831)
- ⚠️ Rename
rollup:before/rollup:reloadhooks to builder-neutral names (#4825) - ⚠️ Remove deprecated and unused options before rc (#4837)
- deno: ⚠️ Remove
deno_deploypreset in favor ofdeno_server(#4841) - presets: ⚠️ Remove
winterjsanddeno-deploypresets (#4857) - ⚠️ Remove deprecated v3 beta aliases (#4960)
- ⚠️ Require Node.js
>=22.22.0(f9894e92, 7c6b29b8)
❤️ Contributors
- Pooya Parsa (@pi0)
- Daniel Roe (@danielroe)
- Diogo Esteves (@dgesteves)
- Sarankumar (@sarankumar1325)
- Max (@onmax)
- Rihan Arfan (@RihanArfan)
- Guillaume AMAT (@GuillaumeAmat)
- Alexander Kolesnik (@sobol-sudo)
- Spoko Dev (@spokodev)
- Yevhenii Chekanskyi (@hellozyemlya)
- @TheForgivenOne
- Huseeiin (@huseeiin)
- Breken (@breken-ai)
- Liang Xu (@lx3133584)
- Christopher Pruijsen (@cpruijsen)
- Manuel Schiller (@schiller-manuel)
- Éverton Toffanetto (@everton-dgn)
- Jainam Gala (@jainamm-gala)
- Agustin18 (@agustin18)
- Aaron Anish Thadathil (@aaronanish-t)
- Yassen Ibrahim (@Yassen717)
- Mochammad Fadhlan Al-Ghiffari (@MFA-G)
- Joseph Hungate (@hungateJoseph)
- Charan Rathore (@charan-rathore)
- Satvik Mishra (@SatvikMishra08)
- Adarsh Yadav (@AdarshYadav9)
- Joshua Reed (@reedjosh)
- Kevin Beier (@tonoizer)
- Prai'ns (@Prains)
- Kaan Çelebi (@kaanisthatyou)
- Btea (@btea)
- Abeer0 (@iiio2)
- Benjamin Canac (@benjamincanac)
- Joaquín Sánchez (@userquin)
- KevinZhou (@pengzh1)
- Guillaume 'G/' Moigneu (@gmoigneu)
- Vittorio Esposito (@vittorioexp)
- Xiang (@Xiang-CH)
- Katja Lutz (@katywings)
- Dog (@dgxo)
- Pavel Dubovitsky (@p-dubovitsky)
- Carlos Precioso (@cprecioso)