Skip to content
Back to blog

We Ran AI Code Analysis on React. It Scored C+.

Priit Kallas

React scores 74 out of 100. A C+.

One of the most important open-source projects in the world. Maintained by Meta’s best engineers. 400,000 lines of code, 555 contributors, 7 years of history. And it gets a C+.

We ran StackGrit’s AI code analysis on the full React monorepo. All 38 packages, every line of code, every commit. The analysis took 83 minutes.

The scorecard

AreaScoreTrend
Data Model85Stable
Architecture82Stable
Team80Stable
Security75Stable
Code Quality72Stable
Test Coverage68Stable
Technologies55Declining

Architecture and data model are React’s strongest areas. The Fiber reconciler is exceptional engineering. But the technologies score (55, declining) drags the overall grade down hard.

The surprising findings

52% of dependencies are outdated, with 60 known CVEs

The biggest finding. Of React’s 364 dependencies, 191 are outdated. 130 are one or more major versions behind. The dependency audit surfaced 60 known CVEs: 3 critical, 23 high severity.

Some specifics: ESLint is 3 major versions behind (7.7 → current 10.x). The Electron dependency for DevTools is 18 major versions behind and formally end-of-life. Yarn 1 is still the package manager when Yarn 4 and pnpm have been standard for years.

These are all development dependencies, so React’s end users aren’t directly affected. But Meta’s own CI pipelines, developer workstations, and DevTools builds are running vulnerable code. At any other company, an auditor would flag this immediately.

A GitHub token is hardcoded in source code

The file scripts/tasks/danger.js contains a real GitHub Personal Access Token. It’s split across two string literals (a common trick to dodge automated scanners) with an inline comment saying it’s “publicly visible on purpose.”

The token has limited public_repo scope. But hardcoded credentials are a supply-chain risk regardless of intent. If the underlying account’s permissions change, so does the blast radius.

93 critical source files have zero tests

The react-dom-bindings package implements the entire DOM mutation layer and synthetic event system. It has 93 source files and zero dedicated test files. Everything depends on integration tests from react-dom.

Three React Server Components bundler packages (Parcel, ESM, and Meta’s internal integration) also have no tests at all. The react-client package has 32 source files and just 2 test files.

An 8,153-line god file

react-devtools-shared/src/backend/fiber/renderer.js is 8,153 lines long with 162 functions. DevTools renderer bridge, fiber inspection, profiler data, owner stack traversal, hook inspection. All in one file.

The second-largest, ReactFiberConfigDOM.js, clocks in at 6,651 lines with 214 functions. And in the reconciler, commitMutationEffectsOnFiber spans 708 lines with 129 conditional branches. One function handling all 25 Fiber work-tag types across three rendering phases.

4x maintenance multiplier on Server Components

React Server Components ship with bundler-specific integrations for webpack, Turbopack, Parcel, and native ESM. These four packages maintain structurally identical directory structures. Every Flight protocol change needs parallel updates across all four. That’s a 4x maintenance multiplier, and code divergence has already started between the Fizz server renderer and the client reconciler.

Bus factor risk on critical subsystems

The React Server Components subsystem (react-server and react-client) is 72-75% authored by a single contributor. Sebastian Markbåge wrote nearly three-quarters of the code in two of React’s most important and rapidly evolving packages.

If that person leaves the project, the team loses deep knowledge of a critical subsystem with no redundancy. Not a code quality problem. An organizational risk that’s invisible without git history analysis.

What React does well

To be clear: a C+ doesn’t mean React is bad. The architecture is excellent. A renderer-agnostic Fiber reconciler powers DOM, React Native, server rendering, and test environments with zero runtime branching. The team ships ~120 commits/month at a 1.85:1 feature-to-fix ratio. Error handling in the render phase is thorough.

The issues above are what every long-lived project accumulates. Not signs of bad engineering. Signs of 7 years and 400K lines of code.

If React has these issues, so does your project

React has one of the best engineering teams in the world. They still have 60 CVEs, untested critical modules, and single-contributor subsystems. Your project probably has similar issues. The difference is whether you can see them.

StackGrit’s AI code analysis covered React’s entire 400K-line codebase in 83 minutes. The full report includes architecture diagrams, team dynamics, prioritized recommendations, and risk assessments.

See the complete React analysis →

Want the same analysis for your codebase? First report is free, no credit card.

Get your free code health report →