Skip to content

docs: next/web-vitals is implemented, not a no-op stub - #3001

Open
ting-hong-shieh wants to merge 1 commit into
cloudflare:mainfrom
ting-hong-shieh:fix/web-vitals-docs
Open

docs: next/web-vitals is implemented, not a no-op stub#3001
ting-hong-shieh wants to merge 1 commit into
cloudflare:mainfrom
ting-hong-shieh:fix/web-vitals-docs

Conversation

@ting-hong-shieh

Copy link
Copy Markdown
Contributor

The README and the shipped migrate-to-vinext skill both list next/web-vitals as an intentional no-op stub. It is a working implementation, and check.ts already says so — the docs are the ones that are wrong.

The implementation

packages/vinext/src/shims/web-vitals.ts subscribes to all six metrics and forwards each to the caller:

onCLS(reportWebVitals);
onFID(reportWebVitals);
onLCP(reportWebVitals);
onINP(reportWebVitals);
onFCP(reportWebVitals);
onTTFB(reportWebVitals);

web-vitals is a real dependency (packages/vinext/package.json:183), the public signature is declared in packages/types/next/next-shims-vinext.d.ts:13, and there is an E2E test ported from Next.js's own suite — tests/e2e/app-router/nextjs-compat/web-vitals.spec.ts, from test/e2e/app-dir/app/useReportWebVitals.test.ts — which asserts the browser actually reports the full set:

const expectedMetricNames = ["CLS", "FCP", "FID", "LCP", "TTFB"];
...
await expect
  .poll(() => [...new Set(reportedMetricNames)].sort().join(","), { timeout: 10_000 })
  .toBe(expectedMetricNamesKey);
expect(eventsCount).toBeGreaterThanOrEqual(6);

The disagreement

Source Says
packages/vinext/src/check.ts:113 supported — "reportWebVitals helper"
README.md API coverage table ⬜ — "No-op (use the web-vitals library directly)"
.agents/skills/migrate-to-vinext/references/compatibility.md Stub — "No-op"

So vinext check and the README told a user opposite things about the same module, and the README's advice actively steered people away from an API that works. The skill matters here too, since it ships to users via npx skills add cloudflare/vinext and is what an agent reads when deciding what to migrate.

Scope

Docs only — no behavior change. I marked the row ✅ per the legend ("full implementation") because the module's only export is useReportWebVitals.

One thing I deliberately did not claim: the Pages Router _app reportWebVitals export is a separate Next.js API and is not wired up (grep -rn reportWebVitals packages/vinext/src/ returns only the shim and the check.ts entry). The new skill note says "not the _app export" so that gap stays visible.

Verification

State: base 7ed5570, head 39a3996.

pnpm run fmt:check passes at head (3098 files). I did not run the E2E suite locally — the spec above is cited as existing CI coverage for the behavior, not as something I re-ran. No source files are touched, so no unit test outcome should change.

Both the README API coverage table and the shipped migrate-to-vinext
skill list `next/web-vitals` as an intentional stub. The shim is a real
implementation: `useReportWebVitals` subscribes to CLS, FID, LCP, INP,
FCP, and TTFB via the `web-vitals` package and forwards each metric to
the caller's callback.

`check.ts` already reports the module as supported, so a user running
`vinext check` and a user reading the README were told opposite things,
and the README's advice to "use the `web-vitals` library directly"
steered people away from a working API.

The `_app`-based `reportWebVitals` export is a separate Pages Router
API and is still not wired up, so the note says so.
@pkg-pr-new

pkg-pr-new Bot commented Aug 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@3001
npm i https://pkg.pr.new/create-vinext-app@3001
npm i https://pkg.pr.new/@vinext/types@3001
npm i https://pkg.pr.new/vinext@3001

commit: 39a3996

@github-actions

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared 39a3996 against base 7ed5570 using alternating same-runner rounds. Next.js was unchanged and skipped.

1 improved · 0 regressed · 5 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 141.4 KB 141.4 KB ⚫ -0.0%
Client entry size (gzip) vinext 128.8 KB 128.8 KB ⚫ -0.0%
Dev server cold start vinext 3.21 s 3.15 s 🟢 -1.8%
Production build time vinext 3.57 s 3.61 s ⚫ +1.3%
RSC entry closure size (gzip) vinext 115.6 KB 115.6 KB ⚫ +0.0%
Server bundle size (gzip) vinext 196.8 KB 196.8 KB ⚫ -0.0%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant