vercel/next.js
The React Framework
Healthy across the board
- ✓Last commit today
- ✓5 active contributors
- ✓Distributed ownership (top contributor 32%)
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
- ⚠Small team — 5 top contributors
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Embed this verdict
[](https://repopilot.app/r/vercel/next.js)Paste into your README — the badge live-updates from the latest cached analysis.
Onboarding doc
Onboarding: vercel/next.js
Generated by RepoPilot · 2026-05-04 · Source
Verdict
GO — Healthy across the board
- Last commit today
- 5 active contributors
- Distributed ownership (top contributor 32%)
- MIT licensed
- CI configured
- Tests present
- ⚠ Small team — 5 top contributors
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
TL;DR
vercel/next.js is the canonical React framework for production, enabling hybrid static and server-side rendering, file-based routing, API routes, React Server Components, and edge/serverless deployment. It solves the problem of building full-stack React applications with zero config by providing a unified build pipeline (Rust-based via SWC compiler in packages/next/src/build/swc), automatic code splitting, and first-class Vercel deployment integration. Monorepo: packages/next/ is the core framework containing src/build/ (SWC/webpack pipeline), src/server/ (Node.js and edge runtime servers), src/client/ (browser-side React code), and src/lib/. The .agents/skills/ directory contains AI agent workflow documentation, and packages/ contains companion tools. The Rust SWC integration lives in packages/next-swc/.
Who it's for
React developers building production web applications who need SSR, SSG, ISR, or edge rendering without manually configuring webpack/babel/routing. Also for framework engineers at Vercel and open-source contributors who maintain Next.js itself, and library authors who need to ensure compatibility with the Next.js App Router and React Server Components.
Maturity & risk
Extremely mature: one of the most starred JavaScript repositories on GitHub (100k+ stars), actively developed since 2016, with a comprehensive test suite, multi-language CI, and daily commits. The presence of .agents/ skills directories, .conductor/ scripts, and .config/ast-grep rules signals a highly organized, enterprise-grade development process. Unambiguously production-ready and battle-tested at massive scale.
Low external risk for consumers, but high internal complexity: the codebase spans JavaScript, TypeScript, and Rust (9.5MB of Rust for the SWC compiler), meaning contributors need multi-language expertise. The monorepo is tightly coupled to Vercel's infrastructure and release cadence, and major versions (App Router introduction in v13) have historically introduced significant breaking changes. Dependency on React canary builds in the vendor layer adds upstream instability risk.
Active areas of work
Active work is visible around: React Server Components and the App Router stabilization, edge runtime improvements (see .agents/skills/dce-edge/SKILL.md for dead-code elimination on edge), feature flags infrastructure (.agents/skills/flags/SKILL.md), React vendoring strategy (.agents/skills/react-vendoring/SKILL.md), and V8 JIT optimization work (.agents/skills/v8-jit/SKILL.md). The .agents/ skills suggest active AI-assisted PR triage and doc update workflows.
Get running
git clone https://github.com/vercel/next.js.git cd next.js pnpm install
Build the core package
cd packages/next pnpm build
To run an example app against local next:
cd ../../examples/basic-css pnpm install pnpm dev
Daily commands:
Install dependencies
pnpm install
Build Next.js itself
pnpm build
Run tests
pnpm test
For development server of a test app:
node packages/next/dist/bin/next dev <app-directory>
Map of the codebase
.github/CODEOWNERS— Defines ownership rules for all directories — critical for understanding who reviews what and for routing PRs correctly..github/actions/needs-triage/dist/index.js— The compiled entry point for the needs-triage GitHub Action — the primary automation logic that labels and routes incoming issues..github/actions/needs-triage/action.yaml— Declares inputs, outputs, and runtime configuration for the needs-triage Action; the contract all callers depend on..devcontainer/devcontainer.json— Defines the reproducible development container used by all contributors, including toolchain versions and feature flags..config/ast-grep/rules/no-context.yml— Core AST-grep lint rule enforcing a critical code pattern constraint across the Rust/Turbopack layer — violations block CI..cargo/config.toml— Workspace-level Cargo configuration governing compiler flags, linker settings, and registry sources for all Rust crates..agents/skills/react-vendoring/SKILL.md— Documents the precise procedure for vendoring React into Next.js — a high-risk, high-frequency operation that must be followed exactly.
How to make changes
Add a new AST-grep lint rule for Rust code
- Create the rule YAML file defining the AST pattern to match and the error message to display. (
.config/ast-grep/rules/your-new-rule.yml) - Add a test fixture YAML with valid/invalid code samples to verify the rule behaves correctly. (
.config/ast-grep/rule-tests/your-new-rule-test.yml) - Run the rule against the test fixtures and commit the generated snapshot output. (
.config/ast-grep/rule-tests/__snapshots__/your-new-rule-snapshot.yml)
Add a new GitHub Issue template
- Create a new YML file in the ISSUE_TEMPLATE directory following the existing bug_report or docs_report structure with required fields. (
.github/ISSUE_TEMPLATE/5.your_template.yml) - Update the config.yml to reference the new template and configure its visibility and routing. (
.github/ISSUE_TEMPLATE/config.yml) - Add CODEOWNERS entries if the new template area needs a specific team to own incoming issues. (
.github/CODEOWNERS)
Add a new AI agent skill
- Create a new directory under .agents/skills/ and add a SKILL.md describing the agent's task, preconditions, and step-by-step procedure. (
.agents/skills/your-skill/SKILL.md) - If the skill references documentation conventions, add a references subfolder with a CODE-TO-DOCS-MAPPING.md or similar guide. (
.agents/skills/your-skill/references/REFERENCE.md) - Register the skill in the Claude plugin marketplace JSON if it should be surfaced in IDE tooling. (
.claude-plugin/marketplace.json)
Update the devcontainer toolchain
- Modify devcontainer.json to add or update feature versions, port forwarding, or post-create commands. (
.devcontainer/devcontainer.json) - Update the Rust install script if the Rust toolchain version or components (e.g. clippy, miri) need to change. (
.devcontainer/rust/install.sh) - Update the Node extras install script for changes to pnpm version, corepack settings, or global packages. (
.devcontainer/node-extras/install.sh) - Update the devcontainer lock file to pin exact feature digest hashes after changing any features. (
.devcontainer/devcontainer-lock.json)
Why these technologies
- TypeScript (GitHub Actions) — Provides type safety for the GitHub Actions SDK calls, reducing runtime errors in automation that runs on every issue/PR event.
- AST-grep (Rust lint rules) — Enables structural code pattern matching in Rust source without writing custom compiler plugins, catching anti-patterns at CI time.
- Dev Containers — Guarantees a reproducible environment across all contributors and CI, eliminating 'works on my machine' issues for a complex multi-language monorepo.
- pnpm — Efficient monorepo package management with strict hoisting controls, essential for a repo with hundreds of packages and workspace dependencies.
- Rust / Cargo (Turbopack) — Provides the performance and memory safety guarantees required for the incremental bundler (Turbopack) that must handle large Next.js apps.
Trade-offs already made
-
Vendoring React into Next.js
- Why: Allows Next.js to ship experimental React features (Server Components, Actions) before they land in stable React releases.
- Consequence: Creates a complex, manual sync process (documented in .agents/skills/react-vendoring/SKILL.md) that must be repeated with every React canary update.
-
Using AI agent skills (.agents/skills/) for repo maintenance tasks
- Why: Encodes institutional knowledge into machine-readable procedures, enabling automation of repetitive high-stakes tasks like vendoring and doc updates.
- Consequence: Requires keeping skill documents accurate and up-to-date; stale skills can cause agents to produce incorrect changes.
-
AST-grep over clippy lints for custom Rust rules
- Why: AST-grep rules are simpler to write and maintain than custom Rust compiler plugins or proc-macro lints.
- Consequence: Less powerful than compiler-integrated lints — cannot perform type-aware analysis, only syntactic pattern matching.
-
Monorepo with 600+ files in a single repository
- Why: Keeps framework, tooling, docs, and examples co-located for atomic changes and unified versioning.
- Consequence: Increases CI time, requires sophisticated CODEOWNERS routing, and demands strict lint/formatting rules to maintain consistency at scale.
Non-goals (don't propose these)
- This repository
Traps & gotchas
- The SWC Rust compiler requires a specific Rust toolchain version — check .cargo/config.toml before building. 2) pnpm is mandatory; npm/yarn will not work due to workspace configuration. 3) Some tests require a running Redis or Postgres instance for ISR/cache tests. 4) The App Router and Pages Router have separate and sometimes conflicting middleware stacks — changes to one rarely apply to the other. 5) React is vendored internally (see .agents/skills/react-vendoring/SKILL.md), so next.js ships its own copy of React canary — do not assume the user's React version is used.
Architecture
Concepts to learn
- React Server Components (RSC) — The App Router is built entirely on RSC, which changes the server/client module boundary model — understanding this is mandatory for working on app-render code
- Incremental Static Regeneration (ISR) — Next.js's core differentiator for cache invalidation — allows static pages to be revalidated on a schedule or on-demand without a full rebuild
- Dead Code Elimination on Edge Runtime — The Edge Runtime only supports a subset of Node.js APIs, requiring aggressive DCE to tree-shake incompatible modules — see .agents/skills/dce-edge/SKILL.md
- SWC (Speedy Web Compiler) — Next.js replaced Babel with this Rust-based compiler for transforms — contributors touching build transforms must work in Rust via packages/next-swc
- Streaming SSR with Suspense — Next.js App Router uses React's streaming APIs to progressively flush HTML — this affects how app-render.tsx handles async Server Components and loading.tsx boundaries
- Module Dual Graph (Server/Client) — Next.js maintains separate module graphs for server and client bundles, and 'use client'/'use server' directives are the boundary markers — misunderstanding this is the #1 source of RSC bugs
- Turbopack (Rust bundler) — The in-progress webpack replacement written in Rust, integrated via vercel/turbo — understanding its incremental compilation model is necessary for build performance work
Related repos
remix-run/remix— Direct alternative React full-stack framework with a different philosophy (no SSG, loader/action model) competing in the same SSR/hydration spacenuxt/nuxt— Vue.js equivalent of Next.js — same hybrid SSR/SSG/edge concepts but for the Vue ecosystem, useful for architectural comparisonvercel/turbo— Contains Turbopack, the Rust-based webpack replacement being integrated into Next.js as the default bundlervercel/swr— Vercel's client-side data fetching library designed to complement Next.js's server-side data patternsswc-project/swc— The upstream Rust-based JavaScript compiler that Next.js vendors and extends via packages/next-swc for its transform pipeline
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for the GitHub Actions PR triage workflow scripts
The .agents/skills/pr-status-triage/ directory contains workflow automation logic (workflow.md, local-repro.md) used by maintainers to triage PRs. The dependencies config shows a GitHub Actions package (@actions/core, @actions/github) with a build step (ncc build lib/index.js), but there are no test scripts defined in the package.json (scripts only has build and types). Adding unit tests for lib/index.js and related logic would catch regressions in the PR triage automation that maintainers rely on daily.
- [ ] Audit
lib/index.js(the entry point built by ncc) to understand what GitHub API calls and triage logic it implements - [ ] Add
jestorvitestas a devDependency alongside the existing@types/nodeandtypescriptdeps - [ ] Create
lib/__tests__/index.test.tswith mocked@actions/coreand@actions/githubto test the triage decision logic in isolation - [ ] Add a
"test": "jest"(or vitest equivalent) entry to thescriptsblock inpackage.json - [ ] Cross-reference
.agents/skills/pr-status-triage/workflow.mdto ensure the test cases cover the documented triage states and transitions
Add a GitHub Actions CI workflow to build and type-check the PR triage action on every PR
The package.json has a build script (ncc build lib/index.js) and a types script (tsc) but the file structure shows no .github/workflows/ entry specifically for validating this action's build. Since this is a compiled GitHub Action (output goes to dist/), it is critical that the dist/ output stays in sync with source changes. A dedicated CI workflow would enforce that pnpm build produces a clean, committed artifact and that TypeScript types pass, preventing broken action deployments.
- [ ] Create
.github/workflows/triage-action-ci.ymltriggered onpull_requestwith path filters for the action's source directory (whereverlib/index.jslives) - [ ] Add a step to install dependencies with
pnpm install --frozen-lockfile - [ ] Add a step to run
pnpm types(tsc type check) and fail the workflow on type errors - [ ] Add a step to run
pnpm buildand then usegit diff --exit-code dist/to verify the committeddist/folder matches the freshly built output - [ ] Reference the
@vercel/nccversion0.38.4pinned in devDependencies to ensure reproducible builds in CI
Expand the ast-grep rule set and add missing snapshot tests for the no-context-turbofmt rule
The .config/ast-grep/rule-tests/__snapshots__/ directory contains snapshot files including no-context-turbofmt-snapshot.yml, but unlike the other rules (no-context, no-context-format, no-err-anyhow, no-map-async-cell, resolved-vc-in-return-type, resolved-vc-in-trait-arguments), there is no corresponding no-context-turbofmt-test.yml in .config/ast-grep/rule-tests/. This means the turbofmt variant of the no-context rule has a snapshot but no executable test driving it, making regressions undetectable.
- [ ] Open
.config/ast-grep/rule-tests/__snapshots__/no-context-turbofmt-snapshot.ymland study the expected matched/unmatched code patterns it documents - [ ] Open the analogous
.config/ast-grep/rule-tests/no-context-test.ymland `.config/ast-grep/rule-tests/no-context-format-
Good first issues
- Add missing edge-case tests for the App Router's parallel routes feature in packages/next/src/server/app-render/ — the route interception + parallel routes combination has sparse test coverage. 2) Improve TypeScript types for the generateStaticParams() return value to surface better errors when returning non-serializable values. 3) Add documentation examples for the lesser-documented unstable_cache() API in docs/02-app/02-api-reference/ following conventions in .agents/skills/update-docs/references/DOC-CONVENTIONS.md.
Top contributors
- @eps1lon — 21 commits
- @mischnic — 16 commits
- @sokra — 12 commits
- @ztanner — 10 commits
- @next-js-bot[bot] — 7 commits
Recent commits
818aa24— [ci] Allow configuring the base URL for preview builds (#93464) (eps1lon)5452439— fix(next/image): Improve error message for private IP (SSRF) rejections (#91686) (rishishanbhag)07f7641— Include deployment id incacheHandlerskeys (#93453) (mischnic)a1c5d3d— [test] Ensure target page is compiled before navigation in instant-navs-devtools (#93365) (eps1lon)af37209— Bump@vercel/ncc(#93459) (eps1lon)9809900— Upgrade React fromda9325b5-20260417tof4e0d4ed-20260429(#93457) (vercel-release-bot)8f77276— Upgrade to swc 65 (#93325) (mischnic)8e4cb62— v16.3.0-canary.9 (next-js-bot[bot])26afa89— Replace Lazy<FxHashMap> static lookups with phf::Map (#93096) (mmastrac)908717a— Drop once_cell from all direct crate deps (#93095) (mmastrac)
Security observations
- Medium · Outdated @actions/core dependency (1.10.0) —
package.json → dependencies → @actions/core. The @actions/core package version 1.10.0 is pinned. Versions prior to 1.10.1 contain a known vulnerability (CVE-2023-37920 / GHSA-7r3h-m5j6-3q42) related to environment variable injection viaexportVariable. Attackers with ability to influence workflow inputs could potentially inject arbitrary environment variables. Fix: Upgrade @actions/core to at least 1.10.1 or the latest stable release to remediate known CVEs. Runpnpm update @actions/coreand verify no breaking changes. - Medium · Outdated @actions/github dependency (5.1.1) —
package.json → dependencies → @actions/github. The @actions/github package is pinned at 5.1.1. This package transitively depends on @octokit/request and node-fetch, which have had security advisories in older versions. Additionally, newer versions of @actions/github include improvements for token handling and retry logic that reduce exposure to race conditions and token leakage. Fix: Upgrade @actions/github to the latest stable version (6.x+). Review the changelog for any breaking API changes before upgrading. - Medium · Outdated @vercel/ncc devDependency (0.38.4) —
package.json → devDependencies → @vercel/ncc. ncc version 0.38.4 bundles dependencies at build time. Older versions of ncc may bundle vulnerable transitive dependencies into the compiled output (dist/index.js), making it harder to patch them later without a full rebuild. The bundled output ships as the production artifact. Fix: Upgrade @vercel/ncc to the latest version. After upgrading, rebuild the bundle (pnpm build) to ensure the latest dependency resolutions are captured in the dist output. - Medium · Minified build artifact obscures dependency vulnerabilities —
package.json → scripts → build, dist/index.js. The build script usesncc build lib/index.js -mwith minification, producing a single bundled and minified dist/index.js. Bundled artifacts make it extremely difficult for automated vulnerability scanners (e.g., Dependabot, Snyk) to detect CVEs in transitive dependencies embedded in the bundle. Vulnerabilities in transitive packages will not be surfaced until a rebuild is triggered. Fix: Ensure the build pipeline is triggered on dependency updates. Consider running a software composition analysis (SCA) tool on the pre-bundle source dependencies. Add a lock-file audit step (pnpm audit) to CI to catch transitive dependency CVEs before bundling. - Low · Outdated TypeScript devDependency (5.1.6) —
package.json → devDependencies → typescript. TypeScript 5.1.6 is not the latest release in the 5.x line. While TypeScript itself is not a runtime dependency and does not directly introduce exploitable vulnerabilities in production, using an outdated compiler may miss type-safety improvements and security-relevant type checking enhancements introduced in later versions. Fix: Upgrade TypeScript to the latest stable 5.x release to benefit from improved type checking and any security-relevant compiler fixes. - Low · Missing
npm audit/pnpm auditstep in build scripts —package.json → scripts. The package.jsonscriptsblock only definesbuildandtypessteps. There is no automated audit step to detect known vulnerable dependencies before building or publishing. This means CVEs in direct or transitive dependencies may go undetected in CI. Fix: Add a"audit": "pnpm audit --audit-level=moderate"script and integrate it into CI pipelines before the build step. Configure Dependabot or Renovate for automated dependency update PRs. - Low · Sensitive GitHub Action token handling — potential secret exposure in logs —
lib/index.. The package depends on @actions/core and @actions/github, which are commonly used to access GITHUB_TOKEN and other secrets. Without reviewing the actual lib/index.js source, there is a risk that debug logging, error messages, or unhandled exceptions may inadvertently print token values or sensitive context data to workflow logs. Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.