Prečo Edge Runtime obmedzuje vývojárov v Next.js Middleware
Ak ste niekedy skúšali v Next.js middleware použiť bcrypt alebo sa pripojiť k databáze, viete o čom hovorím. Next.js middleware je síce výkonný nástroj, ktorý beží pred každou požiadavkou — umožňuje presmerovanie, kontrolu autentifikácie, úpravu hlavičiek a oveľa viac — ale od začiatku bol viazaný na Edge Runtime. To je odľahčené prostredie založené na V8 izolátoch s prístupom iba k Web Standard API.
V praxi? Žiadne natívne Node.js moduly. Žiadny fs, crypto, path. A knižnice ako bcrypt či jsonwebtoken? Zabudnite.
Pre mnohých vývojárov (vrátane mňa) to bola poriadne frustrujúca bariéra. Museli ste vymýšľať zložité obchádzky a robiť architektúrne kompromisy tam, kde to vôbec nebolo nutné. Tak si poďme prejsť celú evolúciu — od pôvodných obmedzení Edge Runtime, cez zavedenie Node.js runtime podpory v Next.js 15.2, jej stabilizáciu v 15.5, až po revolučný prechod na proxy.ts v Next.js 16.
Čo je Edge Runtime a prečo vám stojí v ceste
Edge Runtime je odľahčené prostredie optimalizované na rýchlosť a globálnu distribúciu. Beží na okrajových serveroch (edge nodes) blízko k používateľom, čo znižuje latenciu. Znie to super, však?
Problém je v tom, že táto rýchlosť prichádza za cenu dosť výrazných obmedzení.
Hlavné obmedzenia Edge Runtime v middleware
- Žiadne natívne Node.js API — nemôžete použiť
fs,net,child_processani iné zabudované moduly - Iba ES moduly — CommonJS moduly nie sú podporované
- Limit veľkosti 1-4 MB — celý bundle vrátane závislostí nesmie prekročiť tento limit
- Žiadny prístup k databáze — nemôžete priamo dotazovať databázu
- Žiadny
evalani dynamické vykonávanie kódu — z bezpečnostných dôvodov - Obmedzený prístup k request/response objektom — nemáte plný prístup k telu požiadavky
Čo to znamenalo v reálnom svete? Ak ste chceli v middleware overiť heslo cez bcrypt alebo skontrolovať JWT token pomocou jsonwebtoken, museli ste tieto operácie presunúť do API routes alebo Server Components. V middleware ste mohli akurát tak kontrolovať, či existuje session cookie. Nič viac.
Node.js Runtime v middleware — ako sa to vyvíjalo
Komunita Next.js roky žiadala o možnosť používať plný Node.js runtime v middleware. A úprimne, bolo to oprávnené. Vercel postupne reagoval a riešenie priniesol v niekoľkých krokoch.
Next.js 15.2 — prvý pokus (experimentálna podpora)
V Next.js 15.2 Vercel prvýkrát predstavil experimentálnu podporu Node.js runtime v middleware. Na aktiváciu bolo potrebné pridať experimentálny príznak do konfigurácie:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
nodeMiddleware: true,
},
}
export default nextConfig
Bola to experimentálna funkcia, takže sa nehodila na produkciu. Ale aspoň to bol signál, že sa veci hýbu správnym smerom.
Next.js 15.5 — konečne stabilná podpora
Toto bol ten prelomový moment. Po rozsiahlom testovaní na produkčných aplikáciách Vercel oznámil stabilnú podporu Node.js runtime v middleware v Next.js 15.5. Konfigurácia sa zjednodušila — stačilo nastaviť runtime priamo v middleware súbore:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
export const config = {
runtime: 'nodejs',
matcher: ['/dashboard/:path*', '/api/:path*'],
}
export function middleware(request: NextRequest) {
// Teraz môžete používať akékoľvek Node.js API!
return NextResponse.next()
}
A bolo to. Vývojári konečne mohli priamo v middleware používať bcrypt, pristupovať k databáze, pracovať so súborovým systémom a využívať celý ekosystém npm balíčkov. Konečne žiadne obchádzky.
Praktické príklady s Node.js Runtime
Autentifikácia s JWT a databázou priamo v middleware
Pred Node.js runtime ste museli autentifikáciu riešiť obchádzkou cez API routes. Teraz to ide priamo — a je to oveľa čistejšie:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
import { jwtVerify } from 'jose'
import { db } from '@/lib/db'
export const config = {
runtime: 'nodejs',
matcher: ['/dashboard/:path*'],
}
const secret = new TextEncoder().encode(process.env.JWT_SECRET)
export async function middleware(request: NextRequest) {
const token = request.cookies.get('session')?.value
if (!token) {
return NextResponse.redirect(new URL('/prihlasenie', request.url))
}
try {
const { payload } = await jwtVerify(token, secret)
// S Node.js runtime môžeme priamo pristúpiť k databáze
const user = await db.user.findUnique({
where: { id: payload.userId as string },
select: { id: true, role: true, isActive: true },
})
if (!user || !user.isActive) {
return NextResponse.redirect(new URL('/prihlasenie', request.url))
}
// Kontrola oprávnení na základe role
if (request.nextUrl.pathname.startsWith('/dashboard/admin') && user.role !== 'ADMIN') {
return NextResponse.redirect(new URL('/dashboard', request.url))
}
return NextResponse.next()
} catch {
return NextResponse.redirect(new URL('/prihlasenie', request.url))
}
}
Všimnite si, ako jednoducho teraz vyzerá celý flow — overíme token, dotiahneme si údaje o používateľovi z databázy a skontrolujeme rolu. Všetko na jednom mieste.
Rate limiting s Redis — konečne bez trikov
Ďalší klasický prípad, ktorý bol s Edge Runtime prakticky nemožný — rate limiting s perzistentným úložiskom. S Node.js runtime je to hračka:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
import { Redis } from 'ioredis'
export const config = {
runtime: 'nodejs',
matcher: ['/api/:path*'],
}
const redis = new Redis(process.env.REDIS_URL!)
export async function middleware(request: NextRequest) {
const ip = request.headers.get('x-forwarded-for') ?? 'anonymous'
const key = `rate-limit:${ip}`
const current = await redis.incr(key)
if (current === 1) {
await redis.expire(key, 60) // 60 sekúnd okno
}
if (current > 100) {
return NextResponse.json(
{ error: 'Príliš veľa požiadaviek. Skúste neskôr.' },
{ status: 429 }
)
}
return NextResponse.next()
}
Next.js 16 — z middleware.ts na proxy.ts
A potom prišiel Next.js 16 a všetko sa opäť zmenilo. Súbor middleware.ts bol nahradený súborom proxy.ts. A nie, nie je to len premenovanie — je to koncepčná zmena.
Prečo vlastne proxy?
Termín „middleware" sa neustále zamieňal s Express.js middleware, čo viedlo k nesprávnym očakávaniam (koľkokrát som počul „prečo nemôžem v Next.js middleware robiť to isté čo v Expresse?"). Nový názov „proxy" jasne komunikuje, že tento súbor funguje ako sieťová hranica pred aplikáciou. Čo je presne to, čo middleware v Next.js vždy robil.
Ako migrovať
Migrácia je naozaj priamočiara. Next.js poskytuje codemod, ktorý to spraví za vás:
npx @next/codemod middleware-to-proxy
Alebo ak to chcete spraviť manuálne:
- Premenujte
middleware.tsnaproxy.ts - Premenujte exportovanú funkciu z
middlewarenaproxy - Objekt
configsmatcherzostáva rovnaký
// proxy.ts (Next.js 16+)
import { NextRequest, NextResponse } from 'next/server'
export const config = {
matcher: ['/dashboard/:path*'],
}
// Funkcia sa teraz volá 'proxy' namiesto 'middleware'
export function proxy(request: NextRequest) {
const token = request.cookies.get('session')?.value
if (!token) {
return NextResponse.redirect(new URL('/prihlasenie', request.url))
}
return NextResponse.next()
}
Dôležitá zmena: Proxy beží výhradne na Node.js
Tu je kľúčový rozdiel oproti starému middleware — proxy.ts beží výhradne na Node.js runtime. Edge Runtime nie je podporovaný. Ak z nejakého dôvodu stále potrebujete Edge Runtime, môžete zatiaľ používať middleware.ts, ale je označený ako deprecated. Takže to nie je dlhodobé riešenie.
Edge vs Node.js Runtime — kedy čo použiť
Aj keď Node.js runtime v middleware otvára kopec nových možností, Edge Runtime má stále svoje miesto. Poďme si to rozdeliť.
Kedy siahnuť po Edge Runtime
- Potrebujete minimálnu latenciu a globálnu distribúciu
- Robíte jednoduché operácie — presmerovanie, prepisovanie URL, kontrola cookie
- Geolokačné smerovanie na základe polohy používateľa
- A/B testovanie s jednoduchým rozhodovaním
- Vaša logika nepotrebuje žiadne Node.js API
Kedy si vybrať Node.js Runtime
- Potrebujete pristupovať k databáze priamo v middleware
- Používate knižnice závislé na Node.js (
bcrypt,sharp,ioredis) - Implementujete komplexnú autentifikáciu s overovaním hesiel
- Potrebujete rate limiting s perzistentným úložiskom
- Logika vyžaduje prístup k súborovému systému
- Pracujete s OpenTelemetry a monitoringom
Bezpečnostné odporúčania (toto nepreskakujte)
S väčšími možnosťami prichádza aj väčšia zodpovednosť. Pár vecí, na ktoré by ste nemali zabudnúť:
- Aktualizujte na Next.js 15.2.3+ — opravuje kritickú zraniteľnosť CVE-2025-29927, ktorá umožňovala obísť middleware kontroly. Vážne, aktualizujte hneď.
- Nikdy nespoliehajte iba na middleware — implementujte overovanie na každom mieste prístupu k dátam (Data Access Layer). Middleware je prvá línia obrany, nie jediná.
- Dbajte na výkon — middleware beží pred každou požiadavkou, takže ťažké operácie ho môžu spomaliť. Buďte rozumní.
- Používajte
React.cache()na memoizáciu autentifikačných kontrol v rámci jednej požiadavky - Nastavte správne cookies — HttpOnly, Secure, SameSite atribúty sú nevyhnutné
Prehľad podpory podľa verzií
Pre rýchlu orientáciu (aby ste nemuseli hľadať v dokumentácii):
- Next.js 15.0 — iba Edge Runtime, žiadna podpora Node.js
- Next.js 15.2 — experimentálna podpora Node.js runtime (iba canary)
- Next.js 15.5 — stabilná podpora Node.js runtime
- Next.js 16.0 — prechod na
proxy.ts, Node.js je jediný podporovaný runtime pre proxy - Next.js 17 (plánovaný) — Node.js bude pravdepodobne predvolený runtime
Často kladené otázky
Môžem v Next.js middleware používať bcrypt a iné Node.js knižnice?
Áno, od verzie Next.js 15.5 môžete v middleware používať ľubovoľné Node.js knižnice vrátane bcrypt, jsonwebtoken, ioredis a ďalších. Stačí nastaviť runtime: 'nodejs' v konfigurácii middleware. V Next.js 16+ s proxy.ts je Node.js runtime predvolený a jediný podporovaný.
Aký je rozdiel medzi middleware.ts a proxy.ts v Next.js 16?
V Next.js 16 bol middleware.ts nahradený súborom proxy.ts. Hlavné rozdiely: funkcia sa exportuje ako proxy namiesto middleware, proxy beží výhradne na Node.js runtime (nie Edge) a názov lepšie vyjadruje úlohu sieťovej hranice pred aplikáciou. Logika a matcher konfigurácia zostávajú rovnaké.
Spomalí Node.js runtime v middleware moju aplikáciu?
Pri jednoduchých operáciách je Node.js runtime o niečo pomalší ako Edge Runtime kvôli studeným štartom serverless funkcií. Ale úprimne, pre väčšinu aplikácií je rozdiel zanedbateľný. Ak robíte iba presmerovanie alebo kontrolu cookies, Edge Runtime bude rýchlejší. No pre komplexnejšiu logiku s databázovými dotazmi je Node.js runtime lepšia voľba — eliminuje potrebu ďalších roundtripov.
Je bezpečné robiť databázové dotazy priamo v middleware?
Technicky áno, ak dodržíte správne bezpečnostné praktiky. Dávajte si však pozor na výkon — middleware beží pred každou požiadavkou na zhodujúcich sa cestách. Používajte connection pooling, cache a optimalizované dotazy. Odporúčam tiež implementovať Data Access Layer vzor, kde middleware iba overí session a podrobnejšie kontroly necháte na úrovni prístupu k dátam.
Ako migrovať existujúci Edge Runtime middleware na Node.js?
Je to jednoduchšie, než by ste čakali. Pre Next.js 15.5 pridajte runtime: 'nodejs' do config exportu vášho middleware súboru. Pre Next.js 16+ spustite codemod npx @next/codemod middleware-to-proxy, ktorý automaticky premenuje súbor a funkciu. Potom môžete nahradiť Edge-kompatibilné obchádzky (napríklad jose namiesto jsonwebtoken) za štandardné Node.js knižnice.