Skip to content

Conversation

@MajorLift
Copy link
Contributor

@MajorLift MajorLift commented Nov 3, 2025

Description

This commit enables React Compiler. We can expect long-term UI performance benefits and developer time savings from this change. The Compiler passively and transparently adds memoization code for React components and hooks, among other optimizations, and enforces correctness of new code via the react-compiler/react-compiler ESLint rule.

Due to the large size of the PR, I've created sub-PRs with meaningful commit histories that can be referenced during review. These correspond to the first four commits in this branch:

Review comments or suggestions made in the sub-PRs will be addressed/cherry-picked here. Approvals should be directed towards this PR.

Open in GitHub Codespaces

Changelog

CHANGELOG entry: null (non-user facing but regressions possible)

Related issues

Fixes: #33059

Manual testing steps

  1. Go to this page...

Screenshots/Recordings

Before

After

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Enable React Compiler in the build (Babel/Webpack/ESLint) and refactor codebase, tests, and policies for compiler correctness and stability.

  • Build & Tooling:
    • Enable React Compiler via Babel (babel-plugin-react-compiler) and Webpack (react-compiler-webpack) with centralized reactCompilerOptions and targeted sources gating.
    • Add react-compiler-runtime dependency and wire into build.
    • Update ESLint to include eslint-plugin-react-compiler and enforce react-compiler/react-compiler rule; bump eslint-plugin-react/hooks.
    • Update depcheck and multiple LavaMoat policies to allow new compiler/ESLint packages.
  • Config & Infrastructure:
    • Inject compiler loader before existing TS/JS loaders in Webpack; add Babel plugin and config for React 17 target.
    • Add policy overrides for compiler packages; adjust Babel-related LavaMoat mappings.
  • Codebase Adjustments for Compiler Correctness:
    • Widespread hook/closure fixes (stable deps, useMemo/useCallback, optional chaining, avoid mutation), cleanup of effect deps, and safe timer/abort handling.
    • Replace deprecated/unsafe patterns (e.g., instanceof Array -> Array.isArray, avoid mutating props/params, add key props).
    • Selector/API renames (e.g., useSafeChainsListValidationSelectorgetUseSafeChainsListValidation, use4ByteResolutionSelectorgetUse4ByteResolution); allow undefined ownerId across alerts flow.
    • Tighten types and utilities (asset type guards, safer reducers/selectors, handle undefined confirmation/coverage IDs, misc bug fixes).
    • Tests updated to use renderHook, new selectors, and mocking patterns.
  • Misc:
    • Minor UI/logic tweaks (e.g., fetching/exchange rate flow, polling stability, AssetPage non-mutation, QR camera/init refactors).

Written by Cursor Bugbot for commit 765ad21. This will update automatically on new commits. Configure here.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2025

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-extension-platform Extension Platform team label Nov 3, 2025
@socket-security
Copy link

socket-security bot commented Nov 3, 2025

@socket-security
Copy link

socket-security bot commented Nov 3, 2025

Caution

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Block Low
Publisher changed: npm async-function is now published by ljharb instead of eduardorfs

New Author: ljharb

Previous Author: eduardorfs

From: ?npm/[email protected]npm/[email protected]

ℹ Read more on: This package | This alert | What is new author?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Scrutinize new collaborator additions to packages because they now have the ability to publish code into your dependency tree. Packages should avoid frequent or unnecessary additions or changes to publishing rights.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Block Low
Publisher changed: npm string.prototype.repeat is now published by nicolo-ribaudo instead of mathias

New Author: nicolo-ribaudo

Previous Author: mathias

From: ?npm/[email protected]npm/[email protected]

ℹ Read more on: This package | This alert | What is new author?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Scrutinize new collaborator additions to packages because they now have the ability to publish code into your dependency tree. Packages should avoid frequent or unnecessary additions or changes to publishing rights.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Medium
Deprecated by its maintainer: npm @babel/plugin-proposal-private-methods

Reason: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.

From: ?npm/[email protected]npm/@babel/[email protected]

ℹ Read more on: This package | This alert | What is a deprecated package?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Research the state of the package and determine if there are non-deprecated versions that can be used, or if it should be replaced with a new, supported solution.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@babel/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@metamaskbot
Copy link
Collaborator

metamaskbot commented Nov 3, 2025

✨ Files requiring CODEOWNER review ✨

🔑 @MetaMask/accounts-engineers (2 files, +5 -2)
  • 📁 ui/
    • 📁 components/
      • 📁 app/
        • 📁 identity/
          • 📁 backup-and-sync-features-toggles/
            • 📄 backup-and-sync-features-toggles.tsx +5 -1
      • 📁 multichain/
        • 📁 account-list-item-menu/
          • 📄 account-list-item-menu.js +0 -1

👨‍🔧 @MetaMask/core-extension-ux (1 files, +0 -1)
  • 📁 ui/
    • 📁 components/
      • 📁 multichain/
        • 📁 account-list-item-menu/
          • 📄 account-list-item-menu.js +0 -1

🫰 @MetaMask/core-platform (1 files, +3 -0)
  • 📁 ui/
    • 📁 components/
      • 📁 app/
        • 📁 snaps/
          • 📁 snap-ui-renderer/
            • 📄 snap-ui-renderer.js +3 -0

🎨 @MetaMask/design-system-engineers (2 files, +4 -1)
  • 📁 ui/
    • 📁 components/
      • 📁 component-library/
        • 📁 select-wrapper/
          • 📄 select-wrapper.stories.tsx +2 -1
        • 📁 text-field/
          • 📄 text-field.tsx +2 -0

🧩 @MetaMask/extension-devs (7 files, +587 -266)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +46 -38
      • 📁 experimental/
        • 📄 policy.json +46 -38
      • 📁 flask/
        • 📄 policy.json +46 -38
      • 📁 main/
        • 📄 policy.json +46 -38
    • 📁 build-system/
      • 📄 policy-override.json +18 -1
      • 📄 policy.json +347 -75
    • 📁 webpack/
      • 📄 policy.json +38 -38

💎 @MetaMask/metamask-assets (2 files, +2 -4)
  • 📁 ui/
    • 📁 components/
      • 📁 app/
        • 📁 assets/
          • 📁 token-cell/
            • 📄 token-cell.test.tsx +2 -2
          • 📁 token-list/
            • 📄 token-list.tsx +0 -2

📜 @MetaMask/policy-reviewers (7 files, +587 -266)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +46 -38
      • 📁 experimental/
        • 📄 policy.json +46 -38
      • 📁 flask/
        • 📄 policy.json +46 -38
      • 📁 main/
        • 📄 policy.json +46 -38
    • 📁 build-system/
      • 📄 policy-override.json +18 -1
      • 📄 policy.json +347 -75
    • 📁 webpack/
      • 📄 policy.json +38 -38

Tip

Follow the policy review process outlined in the LavaMoat Policy Review Process doc before expecting an approval from Policy Reviewers.


🔗 @MetaMask/supply-chain (7 files, +587 -266)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +46 -38
      • 📁 experimental/
        • 📄 policy.json +46 -38
      • 📁 flask/
        • 📄 policy.json +46 -38
      • 📁 main/
        • 📄 policy.json +46 -38
    • 📁 build-system/
      • 📄 policy-override.json +18 -1
      • 📄 policy.json +347 -75
    • 📁 webpack/
      • 📄 policy.json +38 -38

@MajorLift
Copy link
Contributor Author

https://github.com/SocketSecurity ignore npm/@babel/[email protected]
This is a transitive dependency of eslint-plugin-react-compiler@npm:^19.1.0-rc.2. We'll be able to remove the deprecated version from the dependency tree once we upgrade to React v18-19, and then to an up-to-date version of eslint-plugin-react-compiler.

https://github.com/SocketSecurity ignore npm/[email protected] npm/[email protected]
New authors are reputable with significant contribution history in related packages.

@MajorLift MajorLift changed the base branch from main to jongsun/chore/251030-enable-rules-of-hooks November 3, 2025 19:48
@metamaskbot
Copy link
Collaborator

Builds ready [3eabf52]
UI Startup Metrics (1311 ± 102 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup13111129155710213891480
load112996813479412041293
domContentLoaded112296113389311991280
domInteractive2314128162151
firstPaint591101134544711231260
backgroundConnect2302192638235246
firstReactRender3120167163548
getState2185072433
initialActions61688617
loadScripts8987381112939701052
setupStore1072631115
numNetworkReqs1367921676
BrowserifyPower User HomeuiStartup20351747278138325552781
load1067914149821113611498
domContentLoaded1059907149021013471490
domInteractive271570174470
firstPaint59819713693749461369
backgroundConnect23621626916252269
firstReactRender27253122731
getState17715029032182290
initialActions51133513
loadScripts834684124120011001241
setupStore1392861228
numNetworkReqs15910331889308318
WebpackStandard HomeuiStartup8266851224948421075
load60454293480608846
domContentLoaded59653590876602820
domInteractive16114981438
firstPaint20855882212169819
backgroundConnect271279133061
firstReactRender28176283336
getState1262841418
initialActions3015349
loadScripts59353390075600812
setupStore1052131216
numNetworkReqs1467519872
WebpackPower User HomeuiStartup13321178194623515311946
load69359610171347801017
domContentLoaded669586916112745916
domInteractive251373205073
firstPaint36983980307619980
backgroundConnect761821472183214
firstReactRender28245982659
getState1396616326154163
initialActions31143514
loadScripts664584905109734905
setupStore96265926
numNetworkReqs1499828675271286
FirefoxBrowserifyStandard HomeuiStartup14771294197313415431743
load1265111316299413221440
domContentLoaded1265111316299413221440
domInteractive1213545460124231
firstPaint------
backgroundConnect4324135205283
firstReactRender26216462644
getState10419720826
initialActions41273312
loadScripts1240109316009013021414
setupStore1265571133
numNetworkReqs1266816761
BrowserifyPower User HomeuiStartup25952290331732928443317
load14731258190520416491905
domContentLoaded14731257190520416481905
domInteractive22796523159362523
firstPaint------
backgroundConnect742717845124178
firstReactRender433267105267
getState15010821034189210
initialActions11146153046
loadScripts14441231187520216231875
setupStore3871705048170
numNetworkReqs1397033599236335
WebpackStandard HomeuiStartup15991412210212716311918
load1365121116268713991541
domContentLoaded1365121116258713991540
domInteractive973023934112158
firstPaint------
backgroundConnect4622134205388
firstReactRender312274133072
getState84436916
initialActions51407417
loadScripts1337119416048313711502
setupStore177207231342
numNetworkReqs1367018767
WebpackPower User HomeuiStartup24872135314734228453147
load14481253179918316771799
domContentLoaded14471253179918316761799
domInteractive1227228866183288
firstPaint------
backgroundConnect1063125275213252
firstReactRender463192185892
getState1197317624134176
initialActions11263161163
loadScripts14121233174017216381740
setupStore3861043677104
numNetworkReqs13461338106240338
📊 Page Load Benchmark Results

Current Commit: 3eabf52 | Date: 11/3/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.05s (±64ms) 🟡 | historical mean value: 1.04s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 737ms (±62ms) 🟢 | historical mean value: 726ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 78ms (±15ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.05s 64ms 1.02s 1.37s 1.26s 1.37s
domContentLoaded 737ms 62ms 706ms 1.03s 940ms 1.03s
firstPaint 78ms 15ms 60ms 216ms 88ms 216ms
firstContentfulPaint 78ms 15ms 60ms 216ms 88ms 216ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 68 Bytes (0%)
  • ui: 497.07 KiB (7%)
  • common: 38.75 KiB (0.45%)

@MajorLift MajorLift marked this pull request as ready for review November 4, 2025 12:24
@MajorLift MajorLift requested review from a team as code owners November 4, 2025 12:24
@github-project-automation github-project-automation bot moved this to Needs dev review in PR review queue Nov 4, 2025
})`;

return ComponentWithRouterHooks;
return useComponentWithRouterHooks;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Misnamed Component Violates React Hook Naming Conventions

The useComponentWithRouterHooks function is named like a React hook but is actually a component. This violates React naming conventions and can confuse tools like React Compiler and linters.

Fix in Cursor Fix in Web

@MajorLift MajorLift added the needs-qa Label will automate into QA workspace label Nov 5, 2025
@MajorLift MajorLift force-pushed the jongsun/chore/251030-enable-rules-of-hooks branch from c9a849d to d3c1f6e Compare November 5, 2025 14:04
@MajorLift MajorLift force-pushed the jongsun/build/251103-enable-react-compiler branch from 3eabf52 to 765ad21 Compare November 5, 2025 14:06
export const getNetworkFees = async (notification: OnChainRawNotification) => {
export const getNetworkFees = async (
notification: OnChainRawNotificationsWithNetworkFields,
) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Redundant Type Guard Breaks Notification Safety

The function signature was changed to accept OnChainRawNotificationsWithNetworkFields instead of OnChainRawNotification, but inside the function there's still a type guard hasNetworkFeeFields(notification) that checks if the notification has network fee fields. This check will always pass due to the stricter type parameter, making the subsequent error throw unreachable. The type guard is now redundant and the error path can never execute, but more critically, this means callers could pass invalid notifications without type safety protection.

Fix in Cursor Fix in Web

confirmed: {
...state.confirmed,
[action.ownerId]: {},
[action.ownerId ?? '']: {},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Undefined ownerId handling causes data collision

The action types changed ownerId from string to string | undefined, and the reducer uses [action.ownerId ?? ''] as a fallback. However, using an empty string as a key when ownerId is undefined will cause all undefined ownerIds to be grouped together under the same empty string key, potentially causing data corruption or unexpected behavior. This should either reject undefined ownerIds or use a more explicit sentinel value.

Fix in Cursor Fix in Web

Copy link
Contributor

@georgewrmarshall georgewrmarshall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving component library changes on behalf of the @MetaMask/design-system-engineers

@github-project-automation github-project-automation bot moved this from Needs dev review to Review finalised - Ready to be merged in PR review queue Nov 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-qa Label will automate into QA workspace size-XL team-extension-platform Extension Platform team

Projects

Status: Review finalised - Ready to be merged

Development

Successfully merging this pull request may close these issues.

4 participants