Published on

Incrementally migrating a NextJS app to typescript

Authors
  • avatar
    Name
    Luke Wood
    Twitter

Incrementally migrating a NextJS app to typescript

I love typescript - but lukewood.xyz was written before I started using typescript in my projects. The lack of a pleasant developer experience has caused me to put off adding features to the site for a long time. In this blog I talk about how I'm incrementally migrating the codebase from javascript to typescript.

Goal

The goal is to make myself productive. I don't want to sink unecessary time porting every last file over to typescript one by one, and typing everything that already works. I do however want to start typing things as I modify them. As such, I'd like my typescript setup to achieve the following:

  • allow the codebase to continue functioning with only the javascript code
  • be able to seamlessly add a new typescript file, and import dependencies from javascript files
  • be able to trivially change JS files to typescript files without the compiler erroring on the first iteration

This requires a pretty loose typescript config to start - but I'd rather start slow and incrementally adopt rules.

Setup

First things first, we need to create a tsconfig. I started by installing my typescript related dependencies:

pnpm install --save-dev typescript @types/react @types/node

and generated a tsconfig:

npx tsc --init --jsx react

NextJS is smart enough to pick up on whether or not you're using typescript - but my workspace also had a jsconfig.json file that I used to declare global paths (i.e. @/components). I had to port all of the settings for my jsconfig.json file over to my new tsconfig.json, but that took about 30~s.

I tested my new setup by porting my 404.js page to 404.tsx. As expected, I had a bit of typing to do but other than that everything worked seamlessly.

Conclusion

That's all it took to start porting lukewood.xyz to typescript. I regret putting this off for so long. I underestimated how friendly the default tsconfig is - it is clearly optimized for the exact journey I described above. If you've been punting off upgrading a codebase, I'd definitely recommend just starting the process incrementally. It was super easy. In the end it took me less than 30 minutes.