Move middleware to proxy, and decide what the new runtime buys
A rename that quietly changes the runtime underneath, and removes the reason one of our comments gives for itself.
next dev warns on every start that the middleware file convention is
deprecated. Next 16 renamed it to proxy — the upgrade guide says "to clarify
network boundary and routing focus" — and ships a codemod:
npx @next/codemod@canary middleware-to-proxy .
Nothing is broken. It is a deprecation, not a removal, and the warning is the whole of the damage today.
It is not only a rename
From the version 16 upgrade guide, in as many words:
The
edgeruntime is NOT supported inproxy. Theproxyruntime isnodejs, and it cannot be configured. If you want to continue using theedgeruntime, keep usingmiddleware.
So renaming the file moves src/middleware.ts from the Edge runtime to Node,
and there is no flag to keep it where it is.
Which makes one of our own comments untrue
src/middleware.ts explains why it verifies nothing before the page does:
Nothing is verified at this point, deliberately. Middleware runs on the Edge runtime with no
node:crypto, and extending a cookie that turns out to be wrong costs nothing.
On Node, node:crypto is there. The constraint that shaped that decision is
gone, so the comment cannot survive the rename unedited — it would be a
statement about this code that is no longer true of it.
The decision this ticket is really for
Two things pull against each other and the rename forces a choice rather than settling one:
- The gate could verify in the proxy now.
matches()andexpectedKey()would run before the page. Whether that is worth doing is open — the page already refuses, and a second place that decides who gets in is a second place to get it wrong. - It stops running at the edge. A Node function on Vercel, on every matched
request, for what is currently a cookie refresh on one route. Fair trade,
probably, but it should be a trade someone made rather than one that arrived
with a
mv.
Config flags carrying the middleware name were renamed too
(skipMiddlewareUrlNormalize → skipProxyUrlNormalize). We set none of them,
so that part costs nothing.