---
title: Getting Started with Next.js 16
date: '2026-02-10'
description: 'What actually changed in Next.js 16, from the "use cache" directive to Turbopack as the default bundler, the React Compiler on by default, proxy.ts in place of middleware, and native View Transitions.'
author: Pablo Fernandez
tags:
  - Next.js
  - React
  - TypeScript
  - Web Development
  - Performance
source: 'https://www.pablofr.com/blog/getting-started-with-nextjs-16'
---
Next.js 16 landed in late 2025, and most of what changed is about caching and compilation moving from things you configure to things that happen by default. This is a tour of the parts I actually reached for when I moved this site onto it.

## The "use cache" directive

The old story for caching a Server Component was a mix of `revalidateTag`, `unstable_cache`, and a lot of guessing about what was static. Next.js 16 turns it into a directive you put at the top of a function. Everything the function returns becomes a cache boundary you can reason about.

```tsx:components/stats.tsx {1}
"use cache"

async function UserStats({ userId }: { userId: string }) {
  const stats = await db.stats.findUnique({ where: { userId } });

  return (
    <div className="grid grid-cols-3 gap-4">
      <div>Posts: {stats.posts}</div>
      <div>Likes: {stats.likes}</div>
      {/* This subtree is cached on its own */}
    </div>
  );
}
```

The win is that the caching lives next to the code it caches, so you can see which parts of the tree are static and which are dynamic without cross-referencing a config file.

## Turbopack is the default bundler

Turbopack is now the default for both development and production, not an opt-in flag. In day-to-day work the thing you feel is Fast Refresh: edits show up fast enough that you stop noticing the compile step, which is the whole point of a dev loop. The build logs also got more useful, with a breakdown of where compile time goes.

## The React Compiler, on by default

New projects ship with the React Compiler enabled. It handles the memoization you used to write by hand, so `useMemo` and `useCallback` mostly leave your code. You describe the render and the compiler works out what can be skipped. The practical effect is fewer dependency arrays to get wrong.

```tsx:components/search.tsx
// No manual useMemo: the compiler decides what to skip.
export function SearchResults({ items, filter }) {
  const filtered = items.filter(item => item.name.includes(filter));

  return (
    <ul>
      {filtered.map(item => <li key={item.id}>{item.name}</li>)}
    </ul>
  );
}
```

## Starting a project

Creating an app is one command, and Turbopack plus the React Compiler are the defaults when you accept the prompts:

```bash
bun create next-app@latest
```

## proxy.ts in place of middleware

Next.js 16 renames the `middleware.ts` file to `proxy.ts`. The export is a plain function that runs before a request is routed, which is where you do redirects, auth checks, and rewrites. Here is the same "send unauthenticated users to the login page" guard I use on this site:

```typescript:proxy.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function proxy(request: NextRequest) {
  const { pathname } = request.nextUrl

  if (pathname.startsWith('/dashboard') && !request.cookies.get('access_token')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return NextResponse.next()
}

export const config = {
  matcher: ['/dashboard/:path*'],
}
```

The matcher decides which paths the function even runs on, so an ordinary page request pays nothing.

## View Transitions

Next.js 16 sits on React 19.2 and exposes the browser's [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API), so page-to-page navigations can animate instead of cutting. You opt a transition in where you want it rather than wiring an animation library through the router.

## Where it leaves you

Most of the release pulls in the same direction: the caching and memoization you used to hand-tune are now defaults you occasionally override, not machinery you assemble. If you are upgrading, the two changes to plan for are the `use cache` model and the `middleware.ts` to `proxy.ts` rename. The rest you mostly get for free by taking the new defaults.
