Upgrading the package changes almost nothing; replacing render with createRoot is what switches the application into concurrent mode.
// 17, and still supported in 18 with a console warning
import ReactDOM from 'react-dom'
ReactDOM.render(<App />, document.getElementById('root'))
// 18
import { createRoot } from 'react-dom/client'
createRoot(document.getElementById('root')).render(<App />)
// note the import path: react-dom/client, not react-dom.
// the old entry point still exists and opts you out of
// every concurrent feature, silently.
Leaving the old call in place is a supported and entirely reasonable first step, and it means useTransition and automatic batching do nothing — which is confusing when somebody adds them and measures no difference. The console warning is the only signal, and it is one line among whatever else is in the console.