Deploy RiskApril 12, 2026 · updated April 15 · 7 min read

We Scored 27 Famous Open Source PRs for Deploy Risk

React Hooks. TypeScript's optional chaining. The Next.js revert-of-a-revert-of-a-revert. We ran 27 landmark open source pull requests through our deploy risk model. The results are not what you'd expect — and one of them only changed a single line.

Deploy risk scoring exists to answer one question before a PR merges: how likely is this to cause a production incident? We built Koalr's model around 36 signals — file churn, blast radius, reviewer load, change entropy, CODEOWNERS compliance, and more.

Most of the time, that model runs against unremarkable internal PRs. But we got curious: what would it have said about some of the most consequential pull requests in open source history? The ones everyone in the industry knows by name.

We pulled 27 of them. Here is what we found.

The obvious ones scored exactly as expected

The tRPC v10 router rewrite — PR #1777 — scored 80. That is Critical. A complete API redesign, flat procedure API replacing nested routers, new type inference surface, zero migration compatibility with v9. No surprises there.

The webpack Module Federation PR scored 66. High. Eighty-five files, a new cross-build runtime dependency surface, failure modes that span independent builds. Also expected.

The surprising ones — landmark PRs that scored lower than their reputation implies

The more counterintuitive results were the landmark PRs that scored lower than their reputation implies.

React PR #14679 — “Enable hooks!” — scored 33 (Low). The diff is the removal of a feature flag. The hooks implementation had already been reviewed, tested, and running behind that flag. The risky work happened in the hundred preceding PRs. The “Enable hooks!” commit itself posed minimal deployment risk. Ecosystem impact and PR-level deployment risk are not the same thing — and the model correctly measures the latter.

Svelte 5 (PR #13701) scored 44 (Medium). Thousands of files changed, but after a year of release candidates, the uncertainty had been methodically eliminated. A high blast-radius merge with low surprise factor is not the same as a risky one. The dangerous PRs were the ones building each new rune.

TypeScript's codebase-to-modules conversion (PR #51387) scored 55 (Medium). It touched every source file in the compiler, but each change followed a predictable mechanical pattern. Uniform, well-tested refactoring is less risky than it looks in the diff viewer.

The revert pattern

One of our favourite examples is Next.js PR #45196. The title reads: “Revert ‘Revert ‘Revert ‘Revert ‘Initial metadata support’’’’”. The PR body says: “Hopefully last time.”

Four consecutive reverts of the same feature, spanning multiple days. This is the deploy risk model's nightmare scenario in plain sight: a feature that could not land cleanly, reverted, re-applied, reverted again, in a loop.

It scored 54.

The score is medium because what actually changed in this specific PR is modest in scope — the instability is in the history, not the diff. The model correctly separates recent churn from current change risk.

There is a risk signal specifically for this pattern — repeated churn on the same file set, with revert commits in the recent history. It is one of the strongest predictors of another rollback.

The one that surprised us most

The Jest-to-Vitest migration in tRPC — PR #3688 — scored 53. Medium risk.

At first glance, that sounds about right for a test runner swap. But look at what actually changed: every single test file in the repository, plus the root configuration, plus the CI pipeline. The surface area was enormous.

The score was “only” 53 because the risk model correctly identified that none of the changed files were production code paths — only test infrastructure. A test runner change cannot break a production deployment directly. What it can do is make future regressions invisible, which is a subtler and harder-to-measure risk.

The model is honest about what it can and cannot see. Broken test infrastructure does not score as a deploy risk — it scores as a coverage risk. Different signal, different response.

The score table

Here are eight of the most interesting of the 27 PRs we scored, with the risk level and the primary reason for the score:

Scores last updated April 15, 2026 and reflect the current model weights. They shift as the model is tuned. Rescore any PR live →

PRScore
facebook/react #14679

Enable hooks!

33Low
microsoft/TypeScript #51387

Convert the codebase to modules

65High
vercel/next.js #45196

Revert "Revert "Revert "Revert 'Initial metadata support'""""

62High
microsoft/TypeScript #33294

Add support for Optional Chaining

55Medium
nodejs/node #41749

lib: add fetch

49Medium
sveltejs/svelte #13701

release svelte 5

44Medium
microsoft/TypeScript #57465

Infer type predicates from function bodies

42Medium
trpc/trpc #3688

chore: replace Jest by Vitest

58Medium

The other nineteen

The remaining nineteen were selected for breadth — major version releases, paradigm shifts, and tooling rewrites across the JavaScript ecosystem. A few scored higher than the eight above; they were not featured because the scores were predictable rather than surprising.

PRScore
vercel/next.js #37551

Implement new client-side router (App Router)

63High
angular/angular #32219

Make Ivy the default in Angular!

42Medium
denoland/deno #26063

2.0.0

48Medium
microsoft/TypeScript #21316

Conditional types

49Medium
sveltejs/svelte #8799

Version Packages (Svelte 4.0.0)

36Medium
webpack/webpack #10838

Merge Module Federation into webpack 5 beta

66High
microsoft/TypeScript #12114

Mapped types

52Medium
microsoft/TypeScript #40336

Template literal types and mapped type "as" clauses

52Medium
facebook/react #11225

ReactDOM.createRoot

19Low
nodejs/node #20876

worker: initial implementation

58Medium
microsoft/TypeScript #39094

Variadic tuple types

47Medium
eslint/eslint #17748

feat!: Update shouldUseFlatConfig and CLI so flat config is default

25Low
nodejs/node #26745

New --experimental-modules implementation

50Medium
vuejs/core #2532

New <script setup> and ref sugar implementation

60High
tailwindlabs/tailwindcss #3905

Embed JIT engine directly into Tailwind

57Medium
facebook/react #13398

Add React.lazy()

21Low
trpc/trpc #1777

Implement new router and procedures

80Critical
babel/babel #5899

Add babel-plugin-syntax-typescript and babel-preset-typescript

45Medium
prisma/prisma #2700

chore: fix 2.0.0 publish

17Low

What this means for your PRs

The open source examples are useful because they are public and well-documented. But the real value of deploy risk scoring is not on landmark PRs with 100 reviewers — it is on the ordinary PR that your team ships on a Thursday afternoon, reviewed by one person in fifteen minutes, that quietly introduces a breaking change nobody caught.

The React hooks PR had the entire React core team reviewing it. It scored 33 — correctly. The dangerous work was already done. The model does not replace review — it gives reviewers a number to orient around. When a PR scores high, the conversation is different. The questions are sharper. The bar for approval is higher.

Most teams do not have the React core team. They have two engineers, a Monday morning deadline, and a PR that looks fine.

That is who this is for.

Score any public PR — no account needed

Try the live risk demo against any public GitHub PR. Paste a URL, get a score in seconds. The same 36-signal model, running live.