pnpm workspace with a Next.js dashboard, a Void API (Cloudflare Worker), and an agent-ready CLI/MCP server.
| Package | Path | Deploy |
|---|---|---|
| Web | apps/web |
Vercel — root directory apps/web |
| API | apps/api |
Void / Cloudflare — see below |
| CLI + MCP | packages/cli |
npm @maxwellcohen/web-perf-report — published by release.yml when its version changes |
Features: CrUX latest/history, PageSpeed analysis, Lighthouse viewer (/viewer), and streaming-timing reports (/stream).
AGENTS.md(also loaded by Claude Code viaCLAUDE.md) — layout, commands, conventions.apps/web/CONTEXT.md— domain glossary.- Run
pnpm checkbefore finishing: typecheck (web, api, cli), lint, and all tests. - For agents consuming the product: use the CLI/MCP server in
packages/clior the site's/llms.txt.
From the repo root:
pnpm install
pnpm dev:web # Next.js at http://localhost:3000
pnpm dev:apiOther root scripts:
| Script | Purpose |
|---|---|
pnpm check |
typecheck (web, api, cli) + lint + all tests |
pnpm test |
Vitest for web, api, and cli |
pnpm typecheck / typecheck:api / typecheck:cli |
per-package type checks |
pnpm lint |
oxlint (web) |
pnpm build:web / build:api / build:cli |
production builds |
Node 24 and pnpm 10 (see packageManager). CI path-filters by package: .github/workflows/ci.yml.
| App | Env file | Required variables |
|---|---|---|
apps/web |
.env (see .env.example) |
WORKER_URL, WORKER_API_KEY, NEXT_PUBLIC_POSTHOG_* |
apps/api |
Cloudflare secrets (void secret put) |
PAGESPEED_INSIGHTS_API, WORKER_API_KEY |
packages/cli |
env WEB_PERF_REPORT_API (optional) |
none |
If you still have .env at the repo root from before the monorepo move, copy it to apps/web/.env.
In the Vercel project for web-perf-reporting:
-
Root Directory —
apps/web -
Install Command (monorepo lockfile at repo root):
cd ../.. && pnpm install --frozen-lockfile
-
Build Command —
pnpm build(runs inapps/web) -
Environment variables —
WORKER_URL(Void API, for examplehttps://web-perf-report-api.<account>.workers.dev) andWORKER_API_KEY(same value as the API worker secret). The Google API key and Turso credentials stay on the API worker. -
Ignored Build Step (optional):
git diff HEAD^ HEAD --quiet -- apps/web pnpm-lock.yaml pnpm-workspace.yaml package.json
The API worker is a separate Cloudflare worker, web-perf-report-api. It reuses the existing KV namespace and api-results R2 bucket, stores CrUX history in a new D1 database, and queues Google PageSpeed and CrUX calls.
From apps/api, with the Void CLI logged into the same Cloudflare account:
pnpm --filter api dev
void secret put PAGESPEED_INSIGHTS_API
void secret put WORKER_API_KEY
pnpm --filter api import:history
void deploy --platform cloudflareimport:history copies Historical_Metrics from Turso into a local SQLite file and prints row counts. After the first deploy creates D1, load that file into the remote database with void db (or wrangler d1 execute) before pointing WORKER_URL at the new worker.
- Web app details:
apps/web/README.md - CLI and MCP server:
packages/cli/README.md - Architecture:
apps/web/docs/architecture-page-speed.md