Codespaces-specific error, can't reconcile different React versions #173800
Replies: 3 comments
-
|
Why It Only Breaks in Codespaces Your local machine and Codespaces are resolving dependencies differently because of how node_modules flattening and hoisting works, plus some subtle changes in package managers or defaults recently: Local Machine is Caching / Hoisting Differently If you’ve been running npm install or yarn install locally for a while, your node_modules might have been “stabilized” (cached), meaning React 17 & React 18 somehow end up not colliding. Your package manager is hoisting one version of React to the top-level in a way that keeps your app running. Codespaces is a Clean Environment Codespaces rebuilds your entire dependency tree from scratch when you create a new one. Because you have two separate package.json files (outer and inner), Codespaces probably installs React twice (once for the root, once for the nested project), leading to two separate React copies in the dependency graph. When React 18’s useId gets called by code expecting React 17’s API surface (or vice versa), you get the crash. Why It Started Breaking in August Most likely, this is due to a new version of npm (v9 → v10) or Yarn’s hoisting behavior changing, or Codespaces changing their default Node version. npm v9/v10 has slightly different hoisting rules than npm v7/v8 — meaning your previously “magically compatible” dependency tree is now getting resolved in a way that leaves two React copies active. Why Local Works Fine Your local computer is likely doing one (or more) of these things: Using a different Node.js version (check node -v locally vs. Codespaces). Using a different package manager version (check npm -v or yarn -v). Benefiting from node_modules cache/lockfile inertia — it may not be doing a fresh install like Codespaces does. So, local is “lucky” enough to produce a flattened node_modules tree where React 17/18 don't conflict — but that’s not guaranteed behavior. You just happen to have a working tree. Options to Keep Your Versions As-Is You don’t have to upgrade/downgrade React just for Codespaces, but you do need to lock your dependency resolution so it behaves predictably everywhere. Here are the best approaches:
Add a .nvmrc or engines field to your root package.json so Codespaces uses the same Node version as local: "engines": { Then tell Codespaces to respect this by adding a .devcontainer/devcontainer.json with: { This will force Codespaces to use the same Node/NPM/Yarn versions as local, making dependency resolution match.
Make sure your root lockfile controls everything (npm package-lock.json or yarn.lock). If you must keep two separate node_modules trees, consider using resolutions (if using Yarn) to enforce a single React version across the workspace: "resolutions": { This way, even if there are two installs, Yarn forces them to be the same.
If your outer and inner projects are meant to coexist but share React, consider setting them up as a proper Yarn workspace or npm workspaces project. TL;DR Why Codespaces Breaks: Clean installs + new npm/node versions now produce a dependency tree with two React copies. Why Local Works: Cached/hoisted node_modules from older installs hide the issue. Fix Without Changing React Versions: Lock Node/npm versions (.nvmrc, engines, .devcontainer). Use one root package-lock.json or Yarn workspace to control hoisting. If using Yarn, force React version resolution with "resolutions". This will make Codespaces behave like your local machine without forcing you to change React versions. |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
|
🕒 Discussion Activity Reminder 🕒 This Discussion has been labeled as dormant by an automated system for having no activity in the last 60 days. Please consider one the following actions: 1️⃣ Close as Out of Date: If the topic is no longer relevant, close the Discussion as 2️⃣ Provide More Information: Share additional details or context — or let the community know if you've found a solution on your own. 3️⃣ Mark a Reply as Answer: If your question has been answered by a reply, mark the most helpful reply as the solution. Note: This dormant notification will only apply to Discussions with the Thank you for helping bring this Discussion to a resolution! 💬 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Select Topic Area
Question
Body
I am getting a runtime error when trying to run my app in a Github Codespaces environment (this does NOT happen when running off local setup), where my entire app crashes with errors like 'Uncaught type error: dispatcher.useId is not a function rendering error'.
I actually know why I'm getting this error, thanks to helpful posts this one: mui/material-ui#31190. My app structure is such that I have an outer directory with a package.json that uses React 18, and my inner project has a package.json that uses React 17. I have fixed this issue in my Codespaces environment by changing these to be the same version, if they're both 17 or 18 the issue goes away.
My question is, why do I only have this error in Codespaces, and is there any configuration I can use to keep my React versions the way they are? What can my local computer do to reconcile these versions that a Codespaces cannot, and is there any config I can use in Codespaces to simulate what my local computer is doing so I can keep my React versions the way they are? Since these versions reconcile in local dev, ppe and prod just fine, I cannot justify changing them just for Codespaces convenience.
NOTE: Codespaces used to reconcile these versions just fine, but something changed in early August and it just stopped working. Older codespaces from July still work fine.
Beta Was this translation helpful? Give feedback.
All reactions