How To Upgrade Existing Projects To Next Js 13

Feb 20 2023 5 minutes
How To Upgrade Existing Projects To Next Js 13

Vercel recently announced Next Js 13 (stable) at Next Js Conf, and it comes with some great and useful features which made Next Js even faster and more efficient in Development and Production.

Overall developer experience has been very smooth with the addition of new features like

  • app Directory (beta)
  • TurboPack ( alpha )
  • New next/image
  • Improved next/link
  • New @next/fonts ( beta )

Well, discuss each new feature in a separate post meanwhile let me introduce them in brief.

You can read about them on Next Js official blog

#app Directory ( beta )

Next Js added a new file structure, now instead of using the pages directory as our main directory, we can also use the app directory which comes with new features and a routing system.

In regular pages structure, we used to organize our projects like the one below.

ProjectName
-pages
    📁blog
        index.js
        [slug].js
    _app.js
    index.js
-public
-src
-styles
-package.json

Now we can use app directory for our main pages like below

ProjectName
-app
    📁blog
        page.js
        [slug].js
        layout.js
    layout.js
    page.js
-public
-src
-styles
-package.json

the new app directory requires page.js instead of index.js, the app directory, and each subdirectory should contain a page.js, and we may create layout.js for layouts, error for errors when components fail to load in each directory but are optional.

This is a new feature and is still in the beta version, so it is not recommended to use in production yet.

#TurboPack ( alpha )

Next Js is replacing Webpack with the Rust-based bundling and build toolTurboPack for better and faster build and reload. It is still in the alpha version.

#@next/fonts

Next Js 13 introduces a new fonts library which will automatically host all the necessary fonts locally inside the project so we don’t have to import from remote CDN while staying in our project which prevents layout shifts when page load delays.

#New next/link

Now we don have to use an extra <a> tag inside <Link> components as new next/link will automatically add an <a> inside to the page which is absolutely awesome.

#New next/image

With improved next/image, now we don’t have to give the height and width for local images, Next Js will automatically set width and height according to the width and height of the image,

Note: this only works for local images if you’re importing images from the remote server you still have to provide width and height in numeric value.

New next/image comes with the native lazy loading support which boosts the performance and load time.

#Upgrading existing projects to Next Js 13

We can incrementally upgrade our existing Next Js 12 or any older Next Js project to Next Js 13, which means we can still use new features of Next Js 13 in our project which are ready for the production environment.

Which are

  • next/image
  • next/link

So in this guide, we’ll see how can we upgrade to Next Js 13 and update our old code base easy to use new components with the help of codemod.

To update your Next js project to Next Js 13 use one of the following commands according to your environment

npm i next@latest react@latest react-dom@latest eslint-config-next@latest
# or
yarn add next@latest react@latest react-dom@latest eslint-config-next@latest
# or
pnpm up next react react-dom eslint-config-next --latest

after running the above command check your package.json for the latest Next Js version

Now we’ll use codemod to incrementally update our codebase for new components and add legacy support if we wish to use older libraries along with the new ones.

#@next/codemod

Next.js provides Codemod transformations to help upgrade your Next.js codebase when a feature is deprecated.

Codemods are transformations that run on your codebase programmatically. This allows for a large number of changes to be applied without having to manually go through every file.

Read more about codemod on the official documentation.

Install codemod in your project if you haven’t already by using the following command

npm install @next/codemod@latest 

#next/link

<Link> components earlier needed and <a> tag as a child to work properly but in Next Js 13 it is no more necessary as next js automatically added a <a> tag in our page so we don’t need to pass <a> tag as a child in <Link> components anymore.

Below is the comparison between the old and new link component

import Link from 'next/link'

// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
  <a className="nav-links">Home</a>
</Link>

// Next.js 13: `<Link>` always renders `<a>` under the hood with all the props
<Link href="/about" className="nav-links">
  About
</Link

to update all your existing <Link> components to new style <Link> tag run the following codemod

npx @next/codemod new-link /pages

// new-link is the codemod defined by next js team
// ./pages is the path where codemod will be executed
npx @next/codemod@latest <transform> <path> // use this syntax 

you can use

--dry to do a dry run, no code will change.

--print to see the changes that happened

Example

npx @next/codemod new-link /pages --dry //will show the pages eligible for change
npx @next/codemod new-link /pages //will change all old <Link> tag to new one
npx @next/codemod new-link /pages --print //will show what changes happened

after running the new-link codemod all your old style <Link> components will update with the new style and all the attributes and props of <a> tag will be assigned to <Link> tag.

import Link from 'next/link'

//OLD
<Link href="/about">
  <a className="nav-links">Home</a>
</Link>

//NEW 
<Link href="/about" className="nav-links">
  About
</Link

#next/image

As soon as we updated our project to Next Js 13 the new next/image library was installed so now we have to follow the style of the new next/image and the old next/image is renamed to next/legacy/image so if we want to see the old image library we have to add support legacy library and we can do this in seconds with the help of codemod given below

//changes all next/image import to next/legacy/image in all files inside ./pages directory
//if you want to do this in another directory the chage ./pages => newPathname
npx @next/codemod@latest next-image-to-legacy-image ./pages 

after running above codemod

below code

import Image1 from 'next/image';
import Image2 from 'next/future/image';

export default function Home() {
  return (
    <div>
      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />
    </div>
  );
}

will change to

// 'next/image' becomes 'next/legacy/image'
import Image1 from 'next/legacy/image';
// 'next/future/image' becomes 'next/image'
import Image2 from 'next/image';

export default function Home() {
  return (
    <div>
      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />
    </div>
  );
}

now you can use old as well as new next/image and gain great performance while maintaining old style of your webpage.

I hope you find this guide helpful, Happy coding 🙂