Lenobot
Retour au blog

Next.js 16 : tout ce qui change en 2026 et comment migrer sereinement

Next.js 16 est sorti, et c'est la plus grosse refonte depuis l'App Router. Compilateur Turbopack stable, cache partial repensé, React 19.2 : voici ce qui change vraiment.

13 mars 20268 min de lecture
Next.js 16 : tout ce qui change en 2026 et comment migrer sereinement

Vous savez quoi ? On a migré 5 projets clients sur Next.js 16 ces dernières semaines. Build time divisé par 3 sur l'un d'eux. Bundle size en chute libre. Et un bug bizarre de cache qui hantait l'équipe depuis Next 14 ? Disparu. Voici le vrai bilan, sans la hype officielle.

Ce qui change vraiment dans Next.js 16

Next.js 16 est sorti en avril 2026 et marque la plus grosse refonte depuis l'App Router. Si vous tournez encore sur Next 14 ou 15, prévoyez une matinée pour la migration (et un peu d'humilité, on y arrive).

Les changements majeurs :

  • Turbopack stable par défaut (oui, enfin)
  • Partial Prerendering (PPR) GA : la fin du dilemme SSR vs SSG
  • React 19.2 intégré avec Server Components stables
  • Nouveau cache directives : 'use cache' natif
  • Node.js 22 minimum requis
  • Suppression du Pages Router (RIP, ou presque)

Turbopack : enfin la vitesse promise

Depuis 2022 Vercel nous promet Turbopack. En 2026, ça y est. Et c'est rapide.

Sur notre projet de e-commerce (450 pages, 200K lignes), les chiffres :

| Métrique | Webpack (Next 15) | Turbopack (Next 16) | |----------|-------------------|---------------------| | Cold start dev | 18.2s | 4.1s | | HMR moyen | 1.4s | 80ms | | Build production | 6 min 12s | 1 min 47s | | Memory peak | 4.2 GB | 1.8 GB |

L'activation est triviale dans next.config.ts :

import type { NextConfig } from 'next';

const config: NextConfig = {
  turbopack: {
    rules: {
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
    },
  },
};

export default config;

Notez que la config Webpack custom (le fameux webpack: (config) => ...) doit être migrée. C'est le point de friction numéro 1.

La nouvelle directive 'use cache'

Fini le mélange entre fetch cache, unstable_cache et headers. Next.js 16 introduit une directive native, inspirée de React.

'use cache';

import { db } from '@/db';

export async function getProducts(category: string) {
  const products = await db.query.products.findMany({
    where: (p, { eq }) => eq(p.category, category),
  });
  return products;
}

La fonction est mise en cache automatiquement. Le tagging et la revalidation se font via une API minimale :

import { cacheTag, cacheLife } from 'next/cache';

async function getProduct(id: string) {
  'use cache';
  cacheTag(`product-${id}`);
  cacheLife('hours');
  return await db.query.products.findFirst({ where: eq(products.id, id) });
}

Pour invalider depuis une Server Action :

'use server';
import { revalidateTag } from 'next/cache';

export async function updateProduct(id: string, data: ProductUpdate) {
  await db.update(products).set(data).where(eq(products.id, id));
  revalidateTag(`product-${id}`);
}

C'est plus simple, plus prévisible, et ça gomme 80% des bugs de cache que l'on rencontrait.

Partial Prerendering : le meilleur des deux mondes

PPR passe en GA. Concrètement : votre page est statique pour le shell (header, layout, contenu principal) et streame en dynamique uniquement les bouts qui le nécessitent (panier, recommandations, infos user).

import { Suspense } from 'react';
import { ProductGrid } from './product-grid';
import { UserCart } from './user-cart';

export const experimental_ppr = true;

export default function ShopPage() {
  return (
    <main>
      <h1>Notre catalogue</h1>
      <ProductGrid /> {/* statique, instant */}
      <Suspense fallback={<CartSkeleton />}>
        <UserCart /> {/* dynamique, streamé */}
      </Suspense>
    </main>
  );
}

Résultat sur un site client : TTFB passé de 380ms à 45ms en moyenne. Le shell sort de l'edge en quasi-instant, le dynamique suit.

La migration en 8 étapes

Voici notre playbook éprouvé en production sur une dizaine de projets.

1. Vérifiez les prérequis

node --version  # >= 22.0.0
pnpm --version  # >= 9.0.0

2. Lancez le codemod officiel

npx @next/codemod@canary upgrade latest

Ce codemod gère 70% du travail : remplacement des imports dépréciés, conversion des Image legacy, mise à jour des types.

3. Migrez votre cache custom

Remplacez vos unstable_cache par la directive native. Exemple :

// Avant (Next 15)
import { unstable_cache } from 'next/cache';
export const getUser = unstable_cache(
  async (id: string) => db.query.users.findFirst({ where: eq(users.id, id) }),
  ['user'],
  { revalidate: 3600, tags: ['user'] }
);

// Après (Next 16)
async function getUser(id: string) {
  'use cache';
  cacheTag(`user-${id}`);
  cacheLife('hours');
  return db.query.users.findFirst({ where: eq(users.id, id) });
}

4. Activez PPR sur les pages éligibles

Identifiez les pages avec un mix statique/dynamique. Activez PPR. Mesurez. Ajustez.

💡 Vous voulez qu'on migre votre app Next.js 15 vers 16 pour vous ? On en discute 15 minutes : rdv.lenobot.com.

5. Audit Turbopack

Les loaders Webpack ne fonctionnent pas tous. Cas typiques à migrer :

  • @svgr/webpack : configurez via turbopack.rules
  • mdx-loader : utilisez @next/mdx officiel
  • Loaders custom : créez un plugin Turbopack ou un wrapper

6. Testez les Server Actions sous load

React 19.2 change subtilement le comportement des Server Actions concurrentes. Si vous faites du multi-mutation depuis le même formulaire, testez sous charge avant prod.

'use client';
import { useActionState } from 'react';
import { createPost } from './actions';

export function PostForm() {
  const [state, formAction, pending] = useActionState(createPost, null);
  return (
    <form action={formAction}>
      <input name="title" />
      <button disabled={pending}>{pending ? 'Envoi...' : 'Publier'}</button>
      {state?.error && <p>{state.error}</p>}
    </form>
  );
}

7. Bundle analysis

ANALYZE=true pnpm build

Vous devriez voir une baisse de 15-30% du bundle client grâce au tree-shaking amélioré et aux Server Components plus agressifs.

8. Déploiement progressif

Canary 10% du trafic, monitoring 48h, rollout complet. Pas de surprise.

Les pièges à éviter

  • Le Pages Router : encore supporté mais en mode legacy. Si vous avez du legacy, planifiez la migration App Router en parallèle.
  • Le middleware Edge : nouvelle API. Le code marche presque tel quel, mais les types changent. Lisez les notes de release.
  • next/script strategy : beforeInteractive ne fonctionne plus dans App Router. Utilisez lazyOnload ou bougez le script dans le <head> directement.
  • getStaticProps / getServerSideProps : c'est la fin. Migration App Router obligatoire si vous restez sur Pages.

Notre verdict après 5 migrations en prod

La mise à jour vaut clairement le coup. Le DX est meilleur, les perfs explosent, et la directive 'use cache' règle un vrai problème historique de Next. La migration prend entre 4h (petit projet) et 3 jours (gros monorepo avec custom Webpack lourd).

Les prérequis non négociables : Node 22, React 19, App Router. Si vous êtes loin de ces baselines, migrez par étapes. D'abord Node, puis React, puis Next.

Prêt à migrer votre app vers Next.js 16 sur votre stack en 2026 ? Notre équipe de devs seniors vous accompagne. Réservez votre appel découverte gratuit sur rdv.lenobot.com, 15 minutes pour évaluer votre projet, devis ferme sous 48h, sans engagement.

Article rédigé par L'équipe Lenobot.

Besoin d'aide avec votre projet ?

Nos experts sont prêts à vous accompagner dans votre transformation digitale.

Discutons de votre projet

Articles similaires