Next.js and React Upgrades: Complexity of New Features and Tooling

Original Title: 416: Upgrading Next.js & React

TL;DR

  • Upgrading Next.js is critical for security and accessing current documentation, as outdated versions can lead to inaccessible resources and potential vulnerabilities.
  • Next.js version upgrades are more impactful than React upgrades due to their server-side code implications, affecting security and the availability of up-to-date documentation.
  • The introduction of Next.js's App Router alongside the Pages Router creates complexity, requiring developers to manage both paradigms and potentially leading to challenges with existing server-side rendering setups.
  • React 19's removal of propTypes support, while potentially improving developer experience by encouraging TypeScript, necessitates code conversion and may impact client-side type checking for projects not fully migrated.
  • Next.js 16's default adoption of Turbopack introduces significant migration challenges, particularly with its strict handling of client components via the use client directive, impacting existing codebases.
  • Turbopack's limited support for CSS Modules features like :global and @export syntax requires syntax adjustments and workarounds, complicating the transition for projects relying on these functionalities.
  • Integrating Turbopack with existing build tools like Webpack and handling specific file imports such as GraphQL can be problematic, often forcing developers to revert to Webpack or seek alternative solutions.

Deep Dive

Upgrading Next.js and React presents a significant challenge for established codebases, requiring substantial effort to adapt to new features and potential deprecations. While staying current offers crucial benefits like access to documentation and security updates, the process is complex, especially when transitioning to new architectural paradigms like Next.js's App Router and grappling with the default adoption of Turbopack.

The decision to upgrade Next.js and React is driven by several critical factors. Foremost among these is the imperative to maintain access to up-to-date documentation; outdated versions can render documentation inaccessible or confusing, forcing developers to resort to less reliable methods like searching GitHub repositories. Security is another major concern, as newer versions often include patches for vulnerabilities and update underlying dependencies, mitigating risks of exploits. Furthermore, staying current ensures compatibility with a broader ecosystem of libraries and tools, preventing integration issues. However, these upgrades are rarely trivial. The transition to Next.js 15, for instance, introduced the split between the "Pages Router" and the new "App Router," creating a dual-support system that complicates development. The App Router, designed with server-side rendering as a priority, requires developers to explicitly flag client components using directives like "use client," a change that can cascade through hundreds of files if not managed carefully.

The adoption of Turbopack as the default in Next.js 16 introduces another layer of complexity. While promising faster compilation, it necessitates significant code modifications, particularly for projects with existing Webpack configurations. Developers may find themselves forced to either migrate their Webpack setups to Turbopack's compatible loaders or use a "webpack" flag to retain the older system, which itself can involve thousands of changes due to deprecated properties or syntax adjustments. Challenges also arise with module handling; for example, Turbopack's specific implementation of CSS Modules may require syntax adjustments for global styles, and it currently lacks support for features like Sass's @export syntax, which is crucial for passing variables between Sass and JavaScript for server-side rendering. Integrating GraphQL, a common requirement for data fetching, also becomes problematic as Turbopack fails to recognize GraphQL loaders, leading to compilation errors. React upgrades, such as the move from 18 to 19, also bring their own set of hurdles. The deprecation of propTypes support, while potentially offset by increased TypeScript adoption, still impacts developer experience and client-side type checking for projects not yet fully converted. Additionally, migrating class components and deprecated APIs like findDOMNode requires extensive code refactoring.

The core implication is that while staying current with Next.js and React is essential for security, documentation access, and ecosystem compatibility, the upgrade process itself is a significant undertaking. The introduction of new architectural patterns like the App Router and default adoption of tools like Turbopack demand substantial engineering effort, often requiring developers to navigate complex dependency changes, new syntax, and potential compatibility issues with existing tooling and codebases, potentially delaying feature development.

Action Items

  • Audit Next.js configuration: Identify and migrate deprecated properties to prevent future build failures (ref: Next.js config).
  • Implement "use client" directive: Add to 700+ component files to resolve Turbopack compatibility issues and enable server-side rendering.
  • Refactor Sass syntax: Update 6+ instances of :global() to global() and remove @export syntax to align with Turbopack's CSS module handling.
  • Investigate GraphQL import errors: Analyze Turbopack's incompatibility with GraphQL loaders to enable compilation of query files.
  • Evaluate Webpack escape hatch: Temporarily force Next.js 16 to use Webpack if Turbopack integration proves unfeasible within 1-2 days.

Key Quotes

"We definitely think of React version upgrades and Next.js version upgrades as different things. Sometimes they are prerequisites. The Next.js ones are a bit more important as 1) the docs for the most recent version tend to be the best and 2) it involves server side code which is important for security reasons. Never has any of it been trivially easy."

The speaker, Chris, highlights that upgrading React and Next.js are distinct processes, with Next.js upgrades being more critical due to improved documentation and security implications of server-side code. He emphasizes that these upgrades are never simple.


"and you know it's there's many reasons that we need to stay up to date overall with client side stuff like react we uh you know we want to stay compatible with different libraries we want to be able to access the latest docs and resources like that's that's huge um if you're on an outdated version and you're trying to find information um you're almost always going to run into some hiccups there"

Chris explains that staying current with client-side libraries like React is essential for maintaining compatibility with other tools and, crucially, for accessing up-to-date documentation. He notes that outdated versions often lead to difficulties when searching for information.


"but we were we were stuck on one version for a while because with uh something server side like like next you've you've there's deployment and all kinds of stuff and uh chris you and i are the are the front end guys and so it's easy for us to update an npm package but when it comes time to actually get that next site deployed and out on the server and working and everything uh most of the time we're going to hit a wall if there's any kind of problem"

The speaker describes a past situation where they were "stuck" on an older version of Next.js due to the complexities of server-side deployment. He points out that while updating an npm package is straightforward for front-end developers, the deployment phase often presents significant challenges.


"and uh this week i guess next 16 dropped and it looked like a good time to be like well maybe we'll just stay on top of it because the last two updates we did were much i don't know i shouldn't say much more painful than this one because this one's not even done yet but it's it's like i don't know like it feels good to stay on top of it because the longer it goes the worse it can be right"

The speaker reflects on the release of Next.js 16, suggesting it's a good time to proactively upgrade. He contrasts this with previous, more painful updates, and expresses a preference for staying current, believing that delaying upgrades can exacerbate problems over time.


"and because we're not like a tight ship with typescript it's not 100 there yet prop types did still have some value so it does feel a little weird ripping them out but usually we rip them out and convert to typescript too but i generally find that to be satisfying work but it's it's tricky because it's not useful like no nobody's paying us any more money the client isn't the app isn't any better you know it can be just zero benefit almost maybe maybe when you're developing and and you like import that component you get slightly better uh type hinting yeah which it's like slightly better dx and who knows maybe we prevented a bug from shipping at one point or something who knows yeah"

The speaker discusses the removal of prop types in React 19, noting that while it feels strange given their codebase isn't fully TypeScript, prop types still offered some value, particularly for editor hints and client-side checking. He acknowledges that the benefit is marginal, potentially improving developer experience and preventing rare bugs.


"but yeah i mean supposedly it it will compile faster um i you know maybe that'll help with like our deployment and and stuff too but i don't i don't think there's like a client side benefit to it well i think of when that i see almost every day is that next takes a little while to compile and by a little while for us it's like what would you say 20 seconds or something only that first time that you speed up the dev environment"

The speaker mentions that Next.js 16 with Turbopack is supposed to compile faster, which might benefit deployment. However, he expresses doubt about any direct client-side performance improvements, noting that the current development environment compilation time of around 20 seconds is a daily annoyance.

Resources

External Resources

Tools & Software

  • Webpack - Compiler used for building projects.
  • Turbopack - New default compiler for Next.js, intended to be faster than Webpack.
  • Cursor - AI tool used to assist with code modifications and problem-solving.
  • Prettier - Code formatter used to ensure consistent code style.
  • Zod - Library used for client-side data validation.
  • Github Actions - Tool used for CI/CD pipelines.
  • NGINX - Server software that can time out waiting for Next.js applications to compile.

Articles & Papers

  • "Next.js 16 documentation and upgrade guide" - Documentation referenced for understanding and implementing Next.js 16.

People

  • Shaw - Guest on the podcast discussing Next.js and React upgrades.
  • Chris - Guest on the podcast discussing Next.js and React upgrades.
  • Chris N's - Editor at Lemon Productions responsible for video output.
  • Robert - Team member who advocated for and implemented TypeScript.

Organizations & Institutions

  • CodePen - Platform where the podcast is hosted and discussed.
  • Lemon Productions - Company responsible for video production.
  • Vercel - Company associated with Next.js documentation issues.

Other Resources

  • React - JavaScript library for building user interfaces.
  • Next.js - React framework for building server-side rendered applications.
  • TypeScript - Programming language that adds static typing to JavaScript.
  • Prop Types - Feature used for client-side type checking in React, deprecated in React 19.
  • Default Props - Feature in React for setting default values for component props.
  • String Refs, Context Types, Fine DOM Node - Deprecated React APIs used in class components.
  • Apollo - GraphQL client library.
  • Urkel - GraphQL client library.
  • Sass - CSS preprocessor used for styling.
  • CSS Modules - Feature for locally scoped CSS.
  • Global Styles - Sass feature for applying styles globally.
  • Export Function - Sass feature allowing variables to be sent from Sass to JavaScript.
  • At Value Syntax - Sass syntax similar to export function.
  • GraphQL - Query language for APIs.
  • Pages Router - Traditional routing system in Next.js.
  • App Router - Newer routing system in Next.js, server-side first.
  • Use Client Flag - Directive in Next.js App Router to indicate client-side components.
  • Use State, Use Effect, Use Ref, Use Sync External Store, Create Context, Use Context - React hooks and context APIs that require the "use client" flag in the App Router.
  • Webpack Configuration - Settings for the Webpack compiler.
  • Next Config - Configuration file for Next.js.
  • MCPServer - AI feature for Next.js that enhances AI models with specific Next.js context and APIs.

---
Handpicked links, AI-assisted summaries. Human judgment, machine efficiency.
This content is a personally curated review and synopsis derived from the original podcast episode.