Public evidence: generated by OpenThunder’s keyless engine (no AI) from vercel/next.js@cbf49db on 2026-10-26. Reproduce it: openthunder lens generate --no-narrate && openthunder lens export. ← Evidence Gallery

next.js: Architecture

next.js · cbf49db30a65 · generated 2026-10-26T06:58:08.586Z · static analysis

Architecture health: 30/100 (F)

Overview

next.js is a JavaScript/TypeScript pnpm monorepo, built with React, Next.js, and Express. It runs as 85 frontends (bundle-analyzer-ui, bench-app-router-server, module-cost, bench-nested-deps, bench-nested-deps-app-router, nested-deps-app-router-many-pages, agent-000-app-router-migration-simple, agent-021-avoid-fetch-in-effect, agent-022-prefer-server-actions, agent-023-avoid-getserversideprops, agent-024-avoid-redundant-usestate, agent-025-prefer-next-link, agent-026-no-serial-await, agent-027-prefer-next-image, agent-028-prefer-next-font, agent-029-use-cache-directive, agent-030-app-router-migration-hard, agent-031-proxy-middleware, agent-032-use-cache-directive, agent-033-forbidden-auth, agent-034-async-cookies, agent-035-connection-dynamic, agent-036-after-response, agent-037-updatetag-cache, agent-038-refresh-settings, agent-039-indirect-proxy, agent-040-instant, agent-041-optimize-ppr-shell, agent-042-enable-ppr, agent-043-view-transitions, agent-046-adopt-partial-prefetching, agent-047-adopt-cache-components, agent-048-prefetch-url-data, agent-049-prefetch-stage, agent-050-optimize-static-shell, agent-051-optimize-partial-prefetching, agent-051-prefetch-until-navigation, agent-052-cache-components-session-isolation, agent-053-cache-components-url-shell, agent-054-cache-components-empty-static-params, agent-055-stale-build-error, agent-057-agent-feedback-anonymization, active-class-name, api-routes-apollo-server, api-routes-apollo-server-and-client, api-routes-apollo-server-and-client-auth, api-routes-cors, api-routes-graphql, api-routes-middleware, api-routes-rest, auth, auth0, basic-css, blog, blog-starter, blog-with-comment, cache-handler-redis, cache-handler-redis-turbo, cloudflare-turnstile, cms-agilitycms, cms-builder-io, cms-buttercms, cms-contentful, cms-cosmic, cms-datocms, cms-dotcms, cms-drupal, cms-enterspeed, cms-ghost, cms-graphcms, cms-kontent-ai, cms-makeswift, cms-payload, cms-plasmic, cms-prepr, cms-prismic, cms-sanity, cms-sitecore-xmcloud, cms-sitefinity, cms-storyblok, cms-takeshape, cms-tina, cms-umbraco, cms-umbraco-heartcore, cms-webiny), backed by 2 shared packages. It stores data in Redis, calls Vercel AI SDK across an explicit AI provider boundary, and integrates with AWS S3. The main structural risks to watch: 15 oversized "god" files and 5 circular import chains. The file with the widest blast radius is bench/basic-app/app/ui/vendor-bulk.js: 24 files depend on it at runtime.

_This entire analysis runs on your machine with no AI required. Connect a model provider to also narrate the reasoning and recover decisions._

Where to start

  1. apps/bundle-analyzer/ Start here: the primary entry point of the system.
  2. bench/basic-app/app/ui/vendor-bulk.js Core module: 24 other modules depend on it, so it shapes much of the system.
  3. packages/eslint-plugin-next/src/utils/define-rule.ts Core module: 22 other modules depend on it, so it shapes much of the system.
  4. packages/eslint-config-next/src/core-web-vitals.ts Core module: 16 other modules depend on it, so it shapes much of the system.
  5. examples/cms-payload/payload-types.ts Core module: 13 other modules depend on it, so it shapes much of the system.
  6. .github/scripts/automated_code_review.js Key flow: Authentication, a high-risk path that enters at invoke automated_code_review.js (.github/scripts/automated_code_review.js).
  7. bench/render-pipeline/analyze-profiles.ts Key flow: Mission execution, a high-risk path that enters at invoke analyze-profiles.ts (bench/render-pipeline/analyze-profiles.ts).
  8. examples/with-fela/FelaProvider.js Key flow: AI provider call, a high-risk path that enters at invoke FelaProvider.js (examples/with-fela/FelaProvider.js).

System map

flowchart TD
  subgraph sys_boundary["next.js"]
    bundle_analyzer_ui["bundle-analyzer-ui"]
    blog_with_comment["blog-with-comment"]
    cms_payload["cms-payload"]
    store_redis[("Redis")]
    collapsed_units["84 more units, no cross-unit imports: bench-app-router-server, module-cost, bench-nested-deps +81"]
  end
  subgraph ai_boundary["AI Provider Boundary"]
    ai_vercel_ai_sdk{{"Vercel AI SDK"}}
  end
  ext_aws_s3{{"AWS S3"}}
  blog_with_comment -->|reads / writes| store_redis
  bundle_analyzer_ui -->|LLM calls| ai_vercel_ai_sdk
  cms_payload -->|API calls| ext_aws_s3
  class bundle_analyzer_ui frontend
  class blog_with_comment frontend
  class cms_payload frontend
  class store_redis store
  class ai_vercel_ai_sdk aiprovider
  class ext_aws_s3 external
  class collapsed_units muted
  %% collapsed (no cross-unit imports): bench-app-router-server, module-cost, bench-nested-deps, bench-nested-deps-app-router, nested-deps-app-router-many-pages, bench-rendering, stats-app, agent-000-app-router-migration-simple, agent-021-avoid-fetch-in-effect, agent-022-prefer-server-actions, agent-023-avoid-getserversideprops, agent-024-avoid-redundant-usestate, agent-025-prefer-next-link, agent-026-no-serial-await, agent-027-prefer-next-image, agent-028-prefer-next-font, agent-029-use-cache-directive, agent-030-app-router-migration-hard, agent-031-proxy-middleware, agent-032-use-cache-directive, agent-033-forbidden-auth, agent-034-async-cookies, agent-035-connection-dynamic, agent-036-after-response, agent-037-updatetag-cache, agent-038-refresh-settings, agent-039-indirect-proxy, agent-040-instant, agent-041-optimize-ppr-shell, agent-042-enable-ppr, agent-043-view-transitions, agent-046-adopt-partial-prefetching, agent-047-adopt-cache-components, agent-048-prefetch-url-data, agent-049-prefetch-stage, agent-050-optimize-static-shell, agent-051-optimize-partial-prefetching, agent-051-prefetch-until-navigation, agent-052-cache-components-session-isolation, agent-053-cache-components-url-shell, agent-054-cache-components-empty-static-params, agent-055-stale-build-error, agent-057-agent-feedback-anonymization, active-class-name, api-routes-apollo-server, api-routes-apollo-server-and-client, api-routes-apollo-server-and-client-auth, api-routes-cors, api-routes-graphql, api-routes-middleware, api-routes-rest, auth, auth0, basic-css, blog, blog-starter, cache-handler-redis, cache-handler-redis-turbo, cloudflare-turnstile, cms-agilitycms, cms-builder-io, cms-buttercms, cms-contentful, cms-cosmic, cms-datocms, cms-dotcms, cms-drupal, cms-enterspeed, cms-ghost, cms-graphcms, cms-kontent-ai, cms-makeswift, cms-plasmic, cms-prepr, cms-prismic, cms-sanity, cms-sitecore-xmcloud, cms-sitefinity, cms-storyblok, cms-takeshape, cms-tina, cms-umbraco, cms-umbraco-heartcore, cms-webiny
  classDef frontend fill:#2563eb,stroke:#93c5fd,color:#fff,stroke-width:2px;
  classDef service fill:#059669,stroke:#6ee7b7,color:#fff,stroke-width:2px;
  classDef store fill:#d97706,stroke:#fcd34d,color:#fff,stroke-width:2px;
  classDef queue fill:#9333ea,stroke:#d8b4fe,color:#fff,stroke-width:2px;
  classDef job fill:#4f46e5,stroke:#a5b4fc,color:#fff,stroke-width:2px;
  classDef external fill:#475569,stroke:#cbd5e1,color:#fff,stroke-width:2px;
  classDef aiprovider fill:#e11d48,stroke:#fda4af,color:#fff,stroke-width:2px;
  classDef library fill:#0891b2,stroke:#67e8f9,color:#fff,stroke-width:2px;
  classDef cli fill:#0d9488,stroke:#5eead4,color:#fff,stroke-width:2px;
  classDef user fill:#64748b,stroke:#e2e8f0,color:#fff,stroke-width:2px;
  classDef muted fill:#334155,stroke:#64748b,color:#cbd5e1,stroke-width:1px;

Critical flows

Authentication high risk

Entry: invoke automated_code_review.js (.github/scripts/automated_code_review.js)

writes files to the working tree (disk); calls an external service (external API); reads or writes persistent records (database)

Authentication guards every protected resource; a regression here can expose data or grant unauthorized access.

sequenceDiagram
  actor C0 as Caller
  participant F0 as automated_code_review.js
  participant F1 as bench-common.mjs
  participant F2 as bench-db.mjs
  participant F3 as sandbox-gate.mjs
  participant F4 as index.js
  participant F5 as next-maintainer-auto-close.js
  participant Disk as disk
  participant External as external API
  participant DB as database
  C0->>F0: invoke automated_code_review.js
  F0->>Disk: writes files to the working tree
  F0->>External: calls an external service
  F1->>Disk: writes files to the working tree
  F2->>DB: reads or writes persistent records
  F2->>Disk: writes files to the working tree
  F3->>Disk: writes files to the working tree
  F4->>External: calls an external service
  F5->>External: calls an external service

Mission execution high risk

Entry: invoke analyze-profiles.ts (bench/render-pipeline/analyze-profiles.ts)

writes files to the working tree (disk); calls an external service (external API)

Mission execution drives autonomous code changes; errors here corrupt runs or the target repository.

sequenceDiagram
  actor C0 as Caller
  participant F0 as analyze-profiles.ts
  participant F1 as benchmark.ts
  participant F2 as client-trace.ts
  participant F3 as artifact.ts
  participant F4 as capture.mjs
  participant F5 as entry.mjs
  participant Disk as disk
  participant External as external API
  C0->>F0: invoke analyze-profiles.ts
  F1->>Disk: writes files to the working tree
  F1->>External: calls an external service
  F2->>Disk: writes files to the working tree
  F2->>External: calls an external service
  F3->>Disk: writes files to the working tree
  F4->>Disk: writes files to the working tree
  F5->>Disk: writes files to the working tree

AI provider call high risk

Entry: invoke FelaProvider.js (examples/with-fela/FelaProvider.js)

Provider calls cost money and shape model output; mistakes leak prompts, burn budget, or route to the wrong model.

sequenceDiagram
  actor C0 as Caller
  participant F0 as FelaProvider.js
  participant F1 as analytics-provider.js
  participant F2 as theme-provider.js
  participant F3 as ably-client-provider.tsx
  participant F4 as ApolloClientProvider.tsx
  participant F5 as InMemoryCache.tsx
  C0->>F0: invoke FelaProvider.js

File changes / writes high risk

Entry: invoke automated_code_review.js (.github/scripts/automated_code_review.js)

writes files to the working tree (disk); calls an external service (external API); reads or writes persistent records (database)

Direct writes to the working tree are hard to reverse; an unguarded write can clobber user code.

sequenceDiagram
  actor C0 as Caller
  participant F0 as automated_code_review.js
  participant F1 as gen.mjs
  participant F2 as bench-collect.mjs
  participant F3 as bench-common.mjs
  participant F4 as bench-db.mjs
  participant F5 as config.mjs
  participant Disk as disk
  participant External as external API
  participant DB as database
  C0->>F0: invoke automated_code_review.js
  F0->>Disk: writes files to the working tree
  F0->>External: calls an external service
  F1->>Disk: writes files to the working tree
  F2->>Disk: writes files to the working tree
  F3->>Disk: writes files to the working tree
  F4->>DB: reads or writes persistent records
  F4->>Disk: writes files to the working tree
  F5->>Disk: writes files to the working tree

Billing high risk

Entry: invoke layout.tsx (examples/with-stripe-typescript/app/layout.tsx)

calls an external service (external API)

Billing touches money and the ledger; errors here are financially material and may be irreversible.

sequenceDiagram
  actor C0 as Caller
  participant F0 as layout.tsx
  participant F1 as billing-meter.js
  participant F2 as stripe.ts
  participant F3 as route.ts
  participant F4 as CheckoutForm.tsx
  participant F5 as CustomDonationInput.tsx
  participant External as external API
  C0->>F0: invoke layout.tsx
  F2->>External: calls an external service
  F3->>External: calls an external service
  F4->>External: calls an external service

Background jobs high risk

Entry: scheduled trigger (bench/dev-validation/benchmark.ts)

writes files to the working tree (disk); calls an external service (external API); returns a response to the caller (client)

Background jobs run unattended; failures are silent and can pile up unnoticed. It also passes through a fragile zone (page.js), widening the blast radius.

sequenceDiagram
  actor C0 as Scheduler
  participant F0 as benchmark.ts
  participant F1 as sandbox-e2e.mjs
  participant F2 as sandbox-ssr.mjs
  participant F3 as page.js
  participant F4 as data.js
  participant F5 as Clock.js
  participant Disk as disk
  participant External as external API
  C0->>F0: scheduled trigger
  F0->>Disk: writes files to the working tree
  F0->>External: calls an external service
  F0-->>C0: returns a response to the caller
  F1->>Disk: writes files to the working tree
  F2->>Disk: writes files to the working tree

Fragile zones

Architecture rules

blocking Route all AI provider calls through the provider abstraction (examples); do not import provider SDKs (Vercel AI SDK) directly in feature modules.

A single provider boundary keeps the system model-agnostic, makes routing/failover/cost-tracking possible, and is the core differentiator of this product.

blocking Change bench/basic-app/app/ui/vendor-bulk.js with care: 24 files depend on it at runtime. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 24, fan-out 0, risk score 48); a careless edit ripples through many dependents.

blocking Change packages/eslint-plugin-next/src/utils/define-rule.ts with care: 22 files depend on it at runtime. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 22, fan-out 0, risk score 44); a careless edit ripples through many dependents.

blocking Change packages/eslint-config-next/src/core-web-vitals.ts with care: 16 files depend on it at runtime. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 16, fan-out 2, risk score 32.5); a careless edit ripples through many dependents.

blocking Change bench/basic-app/app/dashboard/page.js with care: oversized and doing too much. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 0, fan-out 103, risk score 29.8); a careless edit ripples through many dependents.

blocking Change bench/basic-app/app/ui/vendor-blog.js with care: 11 files depend on it at runtime. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 11, fan-out 0, risk score 22); a careless edit ripples through many dependents.

blocking Change packages/devlow-bench/src/index.ts with care: 3 files depend on it at runtime; types used by 9 modules; part of an import cycle. Preserve its public signatures, keep changes additive where possible, and run/extend its tests before and after.

This file has a wide blast radius (fan-in 12, fan-out 2, risk score 20.5); a careless edit ripples through many dependents.

warning Do not add imports that deepen existing import cycles (e.g. packages/devlow-bench/src/index.ts → packages/devlow-bench/src/describe.ts → packages/devlow-bench/src/runner.ts). Break cycles when you touch the files involved.

Circular dependencies make modules impossible to reason about or test in isolation and cause load-order bugs.

advisory Do not add new responsibilities to oversized files (bench/basic-app/app/dashboard/page.js, bench/basic-app/app/docs/page.js, apps/bundle-analyzer/components/diff-table.tsx, .agents/skills/sandbox-bench/scripts/sandbox-e2e.mjs, packages/next-codemod/bin/upgrade.ts); extract new logic into focused modules instead.

Large multi-purpose files are change magnets that accumulate coupling and resist testing; keeping them from growing limits the damage.

warning Respect package boundaries: import across packages via their published entry (e.g. the package name), not deep relative paths reaching into another package's internals.

Deep cross-package imports defeat the module boundary, make refactors brittle, and create hidden coupling the build graph cannot see.