Mike Codeur Formations
Se connecter
Mike Codeur Formations

By Mike Codeur

© 2026 Mike Codeur Formations. Tous droits réservés.

Produit

  • Formations
  • Documentation
  • Blog

Légal & Contact

  • Mentions légales
  • Politique de confidentialité
  • Contact
Get Started

Ready to get started ?

Join thousands of users building amazing things with our platform.

Get Started Free

No credit card required

Newsletter

Restez informé de nos derniers articles et actualités du développement web.

Pas de spam, désabonnement à tout moment

Back to articlesDevelopment

Introduction to Next.js 16

What actually changes when you build with Next.js 16 and React 19: async params, Server Components, Server Actions and Turbopack.

#nextjs#react#frontend
Mike Codeur
August 03, 20265 min
Introduction to Next.js 16
Next.js 16 runs on React 19, and the App Router is no longer a novelty to get used to: it is simply how you write an application. Rather than a changelog, here is what changes when you write code day to day, with examples pulled from a real production app.
The examples in this article come from a project running Next.js 16.2 and React 19.2, in strict TypeScript.

Server Components are the default

A component is a Server Component until you write 'use client'. It runs on the server, never ships to the browser, and can do async work directly:
export default async function CoursesPage() {
  const courses = await getCoursesDal()

  return (
    <ul>
      {courses.map((course) => (
        <li key={course.id}>{course.title}</li>
      ))}
    </ul>
  )
}
No useEffect, no useState, no loading state to hand-roll: the data is there at render time.
The right discipline: keep 'use client' for the leaves of the tree — a form, a menu, an interactive button. Anything that does not need interactivity stays on the server and weighs nothing in the bundle.

params and searchParams are async

This is the change that surprises people the most when migrating, and the one you hit on your very first dynamic page. Route parameters are no longer an object but a promise:
interface PageProps {
  params: Promise<{slug: string}>
}

export default async function Page({params}: PageProps) {
  const {slug} = await params
  return <article>{slug}</article>
}
interface PageProps {
  params: {slug: string}
}

export default function Page({params}: PageProps) {
  return <article>{params.slug}</article>
}
The rule applies everywhere those props show up: page.tsx, layout.tsx, generateMetadata, generateStaticParams.
In strict TypeScript, a forgotten await shows up immediately. In JavaScript you get a silent undefined — type your props, it is the best safety net in this migration.

Server Actions replace most API routes

For a mutation, you no longer need an API route, a serialised fetch and JSON handling on both sides. A server function is enough:
'use server'

import {revalidatePath} from 'next/cache'

export async function updateProfileAction(formData: FormData) {
  const user = await requireActionAuth()

  const parsed = profileSchema.safeParse({
    name: formData.get('name'),
    email: formData.get('email'),
  })

  if (!parsed.success) {
    return {success: false, message: 'Invalid data'}
  }

  await updateUserService({id: user.id, ...parsed.data})
  revalidatePath('/account')

  return {success: true, message: 'Profile updated'}
}
It is called straight from a form, with no network layer to write:
'use client'

export function ProfileForm() {
  return (
    <form action={updateProfileAction}>
      <input name="name" />
      <button type="submit">Save</button>
    </form>
  )
}
A Server Action is a public entry point, exactly like an API route. It must check authentication and validate its input on every call. The fact that it is invoked from a form in your own app proves nothing about the actual caller.

Turbopack in development

The dev server runs on Turbopack. In practice, startup is measured in hundreds of milliseconds and refresh keeps up with your typing:
pnpm dev
▲ Next.js 16.2.10 (Turbopack)
- Local:  http://localhost:3000
✓ Ready in 233ms
On a growing project, this is the kind of detail that changes how you work: you restart without thinking about it.

Where does what go

The most common question when starting with the App Router is not technical, it is about placement. A simple guide:
NeedWhere to write it
Read data for displayServer Component, direct await
Mutate dataServer Action ('use server')
Local state, events, animationsClient Component ('use client')
Machine-facing response (webhook, API)Route Handler (route.ts)
Protect a pageBoth the layout and the page
A layout does not re-render on every client-side navigation. Protecting only the layout leaves a gap: double up the check at the page level.

A structure that lasts

The App Router does not impose an architecture, which is as much a freedom as a trap: nothing stops you from querying the database straight from a component. On a project meant to last, it pays to set a single direction of travel:
1

Presentation

Pages and components. They display; they do not know where data comes from.
2

Data access

A dedicated, cached layer that checks permissions and returns display-ready objects — never raw database rows.
3

Domain

Validation, rules, authorisation. Decisions live here, not in the component.
4

Persistence

The queries. They know nothing about React or HTTP.
The rule that holds it together: never skip a layer. A page importing a SQL query directly is a shortcut that gets expensive six months later.

Takeaway

Next.js 16 does not ask you to relearn React: it moves the default towards the server. The three habits that make the difference:
  • Write server-first, and go client only for what genuinely needs interactivity
  • await your params and searchParams, everywhere
  • Treat every Server Action as a public entry point: authenticate and validate, every time
For the exhaustive list of changes between versions, the official Next.js upgrade guide is the reference to keep open during the migration.
Written by
MC
Mike Codeur
Author
Published on August 03, 2026

Related Articles

Design
Design

Tailwind CSS v4: configuration moves into your CSS

No more tailwind.config.js. v4 moves the whole configuration into your stylesheet, with @theme, @plugin and @custom-variant.

Aug 02, 20264 min
Read more
Tutorial
Tutorial

The Proxy Component in React

A simple pattern to shield your codebase from change: centralise an implementation instead of scattering it across every file.

Aug 01, 20265 min
Read more