DEV Community

Lukasz Ostrowski for Saleor Commerce

Posted on • Edited on

Upgrading React 17 to 18 in a large codebase using AI

Recently, at Saleor, we invested some time into CMD+K (command bar) enhancements. While working on it, I realised our custom solution had become too limited and hard to maintain, so it was time to switch to an existing library.

Our Dashboard - a large and mature codebase - is still running on React 17, which turned out to be a blocker because the library requires v18. You might wonder why we’re still on a five-year-old version. The answer is simple: if we don’t need a change, we prioritise other work. Until now, there was no real need to upgrade.

So, the question was: is the new CMD+K enough of a reason to invest the time in upgrading?

Scope of Changes

Fortunately, changes from 17 to 18 are quite simple:

  • Change how ReactDOM creates a root node (manual change, usually once per project)
  • Upgrade types: get rid of React.FC and fix types in general.

I couldn’t find a codemod that safely migrated React.FC to the shape:

const Component = (props: Pros) => JSX
Enter fullscreen mode Exit fullscreen mode

so I started doing this manually.

Trying an Agent

Manually fixing these would be a monkey job, so it's time to leverage AI for help.

Spoiler: it worked, but I had a few rounds of incrementing prompts:

Precise Prompt

Explaining to the model what to do worked quite well, but it was too literal.

For example, some components used destructuring ({a, b, c}: Props), others used props: Props. This mattered - in some places we passed props to legacy Material UI styling via useStyles(props), so destructuring broke the flow.

I had to do a few rounds to explain exactly what to do.

Focus on Type-Checked Files

Instead of scanning all the files, I told the agent to run tsc first and aggregate files with errors. This kept the AI focused on relevant files.

Working in Batches

Model context was clearly not enough to scan entire codebase. I explicitly asked to work in batches, clearing context in the meantime.

Saving State

At the end of each prompt, I asked to dump the “enhanced" prompt in the .md file, including:

  • The original prompt
  • Its refined version
  • A list of files already fixed
  • Any performance optimisations it used

I committed these files to git to make it easy to pause, resume later, or hand off to another AI. The results were surprisingly good.

Picking up by another agent

To avoid hitting usage limits, I switched between Claude Code, Atlassian's Rovo, and JetBrains Juni. Each could pick up exactly where the other left off using the saved prompt.

Live Editing vs Codegen

While researching this topic, I noticed an interesting approach, heavily used by Juni. It created codemods instead of fixing each file directly in the following flow:

  1. Write a transformation script
  2. Test it on one file
  3. Iterate
  4. Apply it to the whole codebase

In future upgrades, I might skip manual batching and go straight to having AI generate a codemod.

Top comments (0)