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

next.js: Architecture

next.js · bb63c72077ad · generated 2026-10-19T06:57:35.323Z · 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, GitHub, and Vercel Blob. 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/next/src/bundles/webpack/packages/webpack.js Core module: 19 other modules depend on it, so it shapes much of the system.
  5. packages/eslint-config-next/src/core-web-vitals.ts Core module: 16 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"}}
  ext_github{{"GitHub"}}
  ext_vercel_blob{{"Vercel Blob"}}
  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 ext_github external
  class ext_vercel_blob 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/next/src/bundles/webpack/packages/webpack.js with care: 19 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 19, fan-out 0, risk score 38); 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.

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, packages/next/src/bin/next.ts, packages/next/src/cli/internal/static-routes-info.ts, apps/bundle-analyzer/components/diff-table.tsx); 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.