Converting a Next.js app from react-icons to @react-icons/all-files

As your Next.js app grows in complexity, it's good to keep track of what dependencies are having an outsized impact on your bundle size. The Next team has a few tricks up their sleeve to reduce client side bundle size. However, in real life you will run into some packages that are MBs in size and you'll need to find a way to reduce their impact on your bundle size.


The best way to track the impact of each dependency is to use a Next.js specific Bundle Analyzer to see what is contributing to your bundle size.

Photo

You are able to break this down by page, and beyond that you can quickly knock down some large dependencies with dynamic imports


At $WORK we were battling a large First Load JS Shared By All, which was clearly being weighed down by our react-icons package.

Photo

To save you some googling, the problem is react-icons is a legacy monorepo that bundles all of the icons into one package. This means that if you only use one icon, you are still bundling all of the icons. You can try to use every next trick in the book, and you might read that it doesn't happen in NODE_ENV=production, but it does...


Once you learn about all the problems, with react-icons you'll find that there is a new package called @react-icons/all-files that is a drop in replacement for react-icons that allows you to import only the icons you need. It doesn't have the same bundling issues as react-icons and it's supposed to be a drop in replacement. The problem is the newest version of @react-icons/all-files isn't up to date with the latest version of react-icons and it's missing some icons. Oi vey.


The reason is because the @react-icons/all-files package is reportedly too large to upload to npm. An obvious solution would be to try to off ramp from react-icons all together but I found that easier said than done, it's convienent!


The solution


The only solution I have found is installing @react-icons/all-files by linking your package.json to the .tgz file hosted on github:

"@react-icons/all-files": "https://github.com/react-icons/react-icons/releases/download/v4.11.0/react-icons-all-files-4.11.0.tgz",

This seems to dramatically increase install times, but if reducing bundle size is your ultimate goal, than it is worth it.

Using regex to quickly convert your app


When I was converting my teams app, we had over 90 imports of react-icons and I didn't want to manually convert each one. I found that using regex was the best way to quickly convert all of the imports.

I manually wrote (no chat-gpt fr) a regex that would convert all of the imports from react-icons to @react-icons/all-files:

import \{ ([a-zA-Z]+) \}[ ]+from[ ']+react-icons/([a-z]+)
import { $1 } from '@react-icons/all-files/$2/$1

This will only work for files with single react-icon imports, which was about 80% of our imports. For the other 20% I had to manually convert them.


Making these changes dramatically redruced our bundle size and I hope it does the same for you!

Photo