MetaMask / MetaMask/metamask-mobile

Ratchet React Compiler `panicThreshold` in non-prod builds: `critical_errors`, then `all_errors`

Open
#31,507 1 comment 0 reactions 0 assignees View on GitHub
area-performance Sev3 ta-triaged
Dominant language
TypeScript
Stars
3k
Forks
1.7k
Avg merge
1d 14h
Merged PRs (30d)
669

Description

> **Performance audit finding** · Severity: **Medium (tooling/ratchet)** · Effort: Medium, then ongoing · Fix risk: Simple (non-prod builds only) · Test safety net: N/A (build gate)
> Owner: `@MetaMask/mobile-platform (suggested)`
> File: `babel.config.js:67`
> Depends on: #31500 (logger triage — provides the actionable-error list this ratchet burns down)

### What is this about?

`panicThreshold` controls when a React Compiler diagnostic fails the build instead of silently skipping the file. Mobile currently runs the implicit default (`'none'`): every diagnostic is a silent skip, so compiler coverage can regress without anyone noticing. The ratchet makes a *non-production* build progressively intolerant:

| Setting | Build fails on | Use |
|---|---|---|
| `'none'` (current/default) | never — failed files silently skipped | production, permanently |
| `'critical_errors'` | compiler-internal invariant violations | CI/debug gate, first target |
| `'all_errors'` | every diagnostic incl. unsupported syntax | CI/debug gate, end state |

The extension tracks the same ladder as MetaMask-planning#6552 (enable `critical_errors`, fix violations) and #6553 (`all_errors`); its enablement-run split (metamask-extension#38007: 31 actionable errors vs 7,024 unsupported of 7,308 files) shows the actionable set a ratchet has to clear is small once the `Todo` category is excluded.

### Scenario

N/A — build tooling.

### Design

N/A.

### Technical Details

1. Add an env-gated Babel config path (or CI job) that sets `panicThreshold: 'critical_errors'` in the `'react-compiler'` plugin options for non-production builds. Production stays `'none'` permanently — one un-compilable file must never block a release for an optional optimization.
2. Fix the actionable (non-`Todo`) errors surfaced by the #31500 logger until the `critical_errors` gate passes; promote the gate to required CI.
3. Repeat toward `'all_errors'`. What remains after that is the unsupported (`Todo`) set, re-diffed on compiler upgrades — `Todo`s that newly compile are free wins, new errors are regressions the gate now catches.

### Threat Modeling Framework

N/A — non-production build gate; no runtime change.

### Acceptance Criteria

- Non-prod build passes at `panicThreshold: 'critical_errors'` and the gate runs in CI.
- Follow-up ratchet to `'all_errors'` tracked, with the remaining actionable-error count trending to zero.
- Production builds verified unaffected (`'none'`).

### References

- Files: `babel.config.js:67`
- Depends on: #31500; coverage-debt sibling: #31501
- Extension counterparts: MetaMask-planning#6552, #6553; reference implementation metamask-extension#38007 (`--reactCompilerDebug={all|critical|none}`)
- Source: `mms-performance` skill, `mm-react-compiler-error-triage` (MetaMask/skills#49)
- Status: tooling proposal

Contributor guide

Open the contributing guide

Research direction

Start at babel.config.js:67 and inspect the react-compiler plugin options and how non-production builds are selected. Use the #31500 logger output to identify actionable non-Todo errors, then verify the CI gate at critical_errors while keeping production at none. Done means non-prod CI passes at critical_errors, production is unaffected, and the all_errors follow-up is tracked.

Written by the indexing model from the issue text.

Assessment

Tech stack
babel, react, react-native
Domain
build-system, ci-cd, mobile, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.