Skip to content
Lantorian

Next.js8 min read

What's new in Next.js 16

Next.js 16 shipped in October 2025 and 16.3 in August 2026. Turbopack by default, explicit caching, proxy.ts, instant navigations: what you need to read recent code and avoid outdated tutorials.

Four releases in a year

Click a release to see what it brings.

  1. 16.0October 21, 2025
  2. 16.1December 18, 2025
  3. 16.2March 18, 2026
  4. 16.3August 3, 2026
  • Instant navigations

    Partial Prefetching, Instant Insights and the Navigation Inspector in DevTools.

  • 90% less memory

    Leaner next dev, and disk caching for next build too.

  • next/root-params

    Read [locale] from any Server Component.

  • catchError and retry

    Local error boundaries that can refetch server data.

  • TypeScript 7

    Type checking up to 10 times faster in next build.

Our projects start on 16.3. Minor versions don't break anything: upgrade regularly.

Changes that trip people up

Many examples online date from Next.js 13 to 15. If some code won't compile, check these first. Toggle to compare.

middleware.ts becomes proxy.ts

proxy.ts
// proxy.ts (Next.js 16): same logic, Node.js runtime
import { NextResponse, type NextRequest } from 'next/server';

export default function proxy(request: NextRequest) {
  return NextResponse.redirect(new URL('/fr', request.url));
}

params and cookies are async

page.tsx
// Next.js 16: params, searchParams, cookies(), headers() are async
export default async function Page({ params }: PageProps<'/[locale]/invoices/[id]'>) {
  const { id } = await params;
  const theme = (await cookies()).get('theme');
}

revalidateTag takes a profile

actions.ts
revalidateTag('invoices', 'max'); // stale-while-revalidate
updateTag('invoices');            // Server Actions: read your own writes
  • Node.js 20.9 and TypeScript 5.1 minimum.
  • next lint is gone: run eslint directly, and next build no longer lints.
  • Parallel routes require a default.tsx file for every slot.
  • next/image: local images with a query string need images.localPatterns, and images.domains is deprecated in favor of remotePatterns.

Local error boundaries

Since 16.3, catchError creates an error boundary around a single block. Its retry() also refetches Server Components, and it lets notFound() and redirect() through.

src/features/invoices/components/invoices-error.tsx
'use client';

import { catchError, type ErrorInfo } from 'next/error';
import { useTranslations } from 'next-intl';

function InvoicesError(_props: object, { retry }: ErrorInfo) {
  const t = useTranslations('common.errors');
  return (
    <div role="alert">
      <p>{t('loadFailed')}</p>
      <button type="button" onClick={() => retry()}>{t('retry')}</button>
    </div>
  );
}

export default catchError(InvoicesError);

Everyday tooling

For server-side debugging, bundle size analysis and project upgrades.

terminal
next dev --inspect            # attach the Node.js debugger (16.1)
next start --inspect          # same in production (16.2)
next experimental-analyze     # bundle analyzer for Turbopack (16.1)
terminal
npx next upgrade                              # Next.js 16.1+
npx @next/codemod@canary upgrade latest       # from 15: async APIs, proxy, lint...
npx @next/codemod@canary next-lint-to-eslint-cli .  # next lint was removed

Sources: official Next.js blog (16, 16.1, 16.2 and 16.3 posts), checked in September 2026.