What’s New in Next.js 13 — and Why it Matters
In this post, we’ll give a brief intro to Next.js, and then break down some of the new features in Next.js 13 and discuss why they’re important.
Last week, Vercel announced Next.js 13 at their developer conference. The new release, currently in beta, introduces a ton of exciting new features and helps to tell a more powerful and cohesive story around server-side rendering for React, and how it ties together with interactive client-side components.
In this post, we’ll give a brief intro to Next.js, and then break down some of the new features in Next.js 13 and discuss why they’re important.
What is Next.js and Why Use It?
Next.js is a development framework which builds on React by enabling server-side rendering, additional server-side functionality and an improved devleopment and deployment toolchain.
The biggest benefits of server-side rendering with Next.js are in performance and SEO: by rendering on the server, the fully-rendered initial state of an application can be served up on a single request. This means less work for the browser to do, and it also means that the content can be easily indexed by a search engine. It also means rendered data can be cached (in part of in whole) to improve performance even further.
These Next.js features, among others, help to build on React's strong foundation and make up for some of the shortcomings of a purely client-side approach. For any app where performance and SEO matter, Next.js is a welcome addition to the stack. So with the background on Next.js, let's dig into what's coming in the upcoming Next.js 13 release.
app/ Directory for File-Based Routing
One of the greatest features of Next.js is file-based routing. Instead of dealing with gnarly route configuration in a tool like react-router, routes can be specified using the structure of your project directory. Simply place an entrypoint in the pages
directory, and you’ve created a new route.
Next.js 13 builds on this concept and provides redesigned file routing with the new app/
directory. The app directory (which is optional) introduces a new layout structure with several new features and enhancements.
With the new routing scheme, the directory structure is changed somewhat. In Next.js 13, each path in the route now gets a dedicated directory with a page.js
containing the entrypoint for the content. This table shows how basic routing is different in Next.js 12 and 13:
# Route Next.js 12 Next.js 13
/ pages/index.js app/page.js
/blog pages/blog.js app/blog/page.js
/blog/new pages/blog/new.js app/blog/new/page.js
In addition to the page.js
for a route, the new structure lets us include several other special files in each path directory, including: layout.js
, a layout component for the path (and all sub-paths); loading.js
, a component for an instant loading state using React.Suspense
under the hood; and error.js
, a component rendered when the main component fails to load.
Because each path is now its own directory, we can also colocate source files inside of our path directories. We can include other components, as well as styles, tests, etc:
app/blog/page.js
app/blog/Header.js
app/blog/Header.css
app/blog/Header.test.js
File-based routing has always been a great feature, and the new app/
directory takes it to the next level. It simplifies development, and (perhaps on a nostalgic note), helps bring back the utter simplicity of building more static sites: the content paths match the content directory structure . Once again, use of the new app/
directory if fully optional, so you don’t have to migrate to the new structure right away.
React Server Components
The next exciting change in Next.js 13 is the addition of support for React server components. Server components let us execute and render React components on the server-side for faster delivery, smaller JavaScript bundle, and lower client-side rendering cost.
Additionally, depending on what kind of data is required to render a route, server components can be automatically cached either at build-time or at runtime for additional performance benefits.
The capabilities of server and client components do vary somewhat, so you will need to architect your application accordingly. The following table, taken from the documentation, outlines what capabilities the two different kinds of components have and what they are best used for.
Server & client components can be mixed, meaning you can use server components for the fast-loading, non-interactive parts of your application, but leverage client components where needed for interactivity, browser APIs, etc.
When building out client components in your Next.js app, you’ll use the 'use client';
directive at the top of the file to mark it accordingly. Note that if you’re using third-party packages, you may need to create a client wrapper for those components.
Async Components & Data Fetching
Next.js 13 also introduces a new approach to fetching data for server-rendered components: async components. With async components, we can render components using Promises with async & await. If we need to fetch data from an external service or other API returning a Promise, we declare the component as async and simply await the result:
async function getData() {
const res = await fetch('https://api.example.com/...');
return res.json();
}
export default async function Page() {
const name = await getData();
return '...';
}
Previous versions of Next.js used an entirely different API to resolve the request data outside of the lifecycle of the component, which then is used as component props. This example shows a Next.js 12 approach to loading data from an external service:
// This gets called on every requestexport async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
The older approach is still supported but not inside of the new app/
directory. If you want to take advantage of the new app/
directory structure and all of its cool new features, you’ll need to update your server components. If you’re not ready to, however, you can still use the Next.js 12 pages/
routing for your app.
Also note that async rendering and Promise support is not yet available for client components — but it is on the way via a proposed new use()
hook:
In the meantime, however, client-side components can use more traditional async methods, such as React.Suspensealongside lifecycle hooks like useEffect()
, or using a 3rd-party library which enables such functionality.
Turbopack for lightning fast bundling
The last major change introduced with Next.js 13 is a new JavaScript bundler, Turbopack, billed as the “successor to Webpack”. Webpack, one of the most ubiquitous JavaScript build tools, is insanely configurable and powerful but can also be quite slow and clunky.
Turbopack is authored by the creators of Webpack, but is built with Rust and promises to be 700x faster than the original Webpack (and 10x faster than Vite, a more modern alternative). For a full breakdown of the similarities and differences, check out the Webpack & Turbopack comparison.
Be aware that Turbopack is currently in alpha and is not yet ready for production usage, but it’s definitely in good enough shape for a test-drive in development. Also note that Turbopack currently lacks a public plugin API (which is one of Webpack’s biggest strengths), but this will be addressed in the future.
If you create a new Next.js 13 app, you can try out the new Turbopack bundler using next dev --turbo
to start your dev server.
Other Improvements
Though we focused on some of the big ticket items in this post, there are a number of other important features included in Next.js 13:
- Better image loading support & performance with
next/image
- Improved font performance with
next/font
- Link API improvements with
next/link
For a full list of changes, have a look at the Next.js 13 Blog Post from Vercel.
Recap — Server-Side React is Growing Up
In this post, we covered a number of new features in Next.js 13. While the new features described here touch on a variety of different areas, the overall theme to me is a maturing of the framework. Next.js 13, along with upcoming changes in React itself are beginning to tell a solid, coherent story around mixing React on the server and the client.
If you haven’t yet looked at Next.js or server-side React, now is a great time to check it out!