company logo

Upgrading To Next.js 13

Posted on May 26, 2023
Written by Seth Nelson

Vercel recently announced the long-awaited upgrade for the Next.js framework: Next.js 13! In software terms, it is a significant upgrade. It introduced numerous highly anticipated features. However, it's common to wait until the release from beta to ensure it's production-ready before upgrading the entire codebase. It was announced to be production-ready at the end of 2023.

We recently decided to upgrade our home site to leverage its out-of-the-box features and further improve performance. If you've been hesitant about upgrading your Next.js application, look no further. I've compiled a comprehensive yet simple guide.

The Changes

While there were a lot of features added with Next.js 13, I want to give you the quickest rundown of what is needed from a base level. Some components were upgraded that are likely used in every Next.js application. There are ways to work around these changes or handle the upgrades yourself.

The <Image /> Component

Next.js 12 introduced a temporary import called /next/future/image that contained some new improvements like less client-side js, updated processes to extend styles, and native browser lazy loading. Next.js 13 incorporates these features as standard with next/image. This does require some updating and refactoring if you want to re-style your images.

If you prefer to upgrade later without updating your existing <Image /> components, you can avoid this by running a simple codemod:

npx @next/codemod@latest next-image-to-legacy-image ./pages

This command will safely rename any imports from next/image to next/legacy/image in Next.js 10, 11, or 12 versions, as shown below:

// old import import MyImage from 'next/image' // new import import MyImage from 'next/legacy/image'

Routing and the <Link /> Component

In older versions of Next.js, a child <a> tag was required for a <Link> component. (There was an experimental option in version 12.2). Next.js 13 no longer requires the <a> tag within <Link> components by default, as <Link> now renders the <a> tag automatically.. This cleans up your code base quite a bit. Next.js provides a codemod to simplify this conversion:

npx @next/codemod@latest new-link ./pages

This command will safely remove any <a> tags inside of existing <Link> components in Next.js 10, 11, or 12 versions like so:

// old method <Link href="/contact"> <a>Contact</a> </Link> // new method <Link href="/contact"> Contact </Link>

Note: Some items may not be auto-fixed successfully. In such cases, the component will contain a legacyBehavior prop and function as before. You can also manually remove the tag if desired.

Optional New Features

The app Directory

This is a significant upgrade, and I recommend reading more about it here. This is intended to be a page by page migration, but requires a decent lift since all of your pages and structure will have to be modified. It is still in beta, so for now, it is set through an optional flag.

Static Metadata and Typings

Next.js 13 introduces built-in SEO support, allowing metadata definition inside individual components for improved SEO. A few examples from the Next.js documentation:

Static Meta Data

import type { Metadata } from 'next' export const metadata: Metadata = { title: 'Products', description: 'A comprehensive list of products we offer.', } export default function MyPage() { return '...' }

Dynamic Meta Data

import type { Metadata } from 'next' async function getProduct(id) { const res = await fetch(`https://.../api/products/${id}`) return res.json() } export async function generateMetadata({ params }): Promise<Metadata> { const product = await getProduct( return { title: product.title } } export default async function Page({ params }) { const product = await getProduct( // ... }

The <Script /> component

If you are using the new beta app folder structure, beforeInteractive scripts have been relocated from _document.js to app/layout.tsx.

Font Optimization

Next.js 13 introduces a new font module next/font that enables customization of the font loading process while maintaining speed and privacy. It is not required for the upgrade.


Minimum Versions Required for Upgrade

To upgrade to Next.js 13, you need to update the following dependencies to their minimum versions:


      yarn add react@18.2.0 or npm upgrade react@18.2.0


      yarn add react-dom@18.2.0 or npm upgrade react-dom@18.2.0


      npm i -g node@16.8

Why Should You Upgrade?

Keeping your application up to date

Keeping your application up to date is essential. Upgrading ensures compatibility with the latest packages, avoiding potential issues caused by deprecated or outdated dependencies. Regular updates provide peace of mind and keep your app running smoothly, similar to updating firmware or operating systems on devices.

Future releases could cripple your application

Software moves quickly. While we are busy building products, teams are constantly improving the tools we use to build and maintain these products. This rapid pace of development in the software industry means that new versions and updates are released frequently. Upgrading to newer versions is often necessary, as it can prevent us from encountering issues with deprecated or incompatible dependencies. By staying up to date with package upgrades, we can avoid potential difficulties and ensure the smooth functioning of our applications.

Thanks for reading!

Resource Links

Seth Nelson photo
Seth Nelson
Software Engineer
company logo
ServicesTeam IntegrationStrategy and DesignCustom TeamsProof of Concept
TeamOur EmployeesCareersAbout UsOur Customers
TestimonialsAtomic ObjectSimple ThreadZEAL
Contact Us
176 W. Logan St. #335
Noblesville IN, 46060