From 4d9382d6c6d13b868c982e395a379c7ea435c1e1 Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Sun, 22 Mar 2026 14:44:35 -0500 Subject: [PATCH 1/3] docs: refresh AI guidance for vp and Vite 8 --- .agents/skills/migrate-to-vinext/SKILL.md | 32 +++++----- .../references/compatibility.md | 2 + .../references/config-examples.md | 7 ++- .../references/troubleshooting.md | 6 +- AGENTS.md | 61 +++++++++---------- CLAUDE.md | 2 +- CONTRIBUTING.md | 8 +-- README.md | 58 +++++++++--------- 8 files changed, 94 insertions(+), 82 deletions(-) diff --git a/.agents/skills/migrate-to-vinext/SKILL.md b/.agents/skills/migrate-to-vinext/SKILL.md index d2030d3d7..ade817563 100644 --- a/.agents/skills/migrate-to-vinext/SKILL.md +++ b/.agents/skills/migrate-to-vinext/SKILL.md @@ -7,6 +7,8 @@ description: Migrates Next.js projects to vinext (Vite-based Next.js reimplement vinext reimplements the Next.js API surface on Vite. Existing `app/`, `pages/`, and `next.config.js` work as-is — migration is a package swap, config generation, and ESM conversion. No changes to application code required. +For user projects, prefer plain Vite 8. vinext still supports Vite 7 for older setups, but new migrations should assume Vite 8 unless you are unblocking a specific compatibility issue. + ## FIRST: Verify Next.js Project Confirm `next` is in `dependencies` or `devDependencies` in `package.json`. If not found, STOP — this skill does not apply. @@ -44,7 +46,7 @@ See [references/compatibility.md](references/compatibility.md) for supported/uns Run `vinext init`. This command: 1. Runs `vinext check` for a compatibility report -2. Installs `vite` as a devDependency (and `@vitejs/plugin-rsc` for App Router) +2. Installs `vite`, `@vitejs/plugin-react`, and App Router-only deps (`@vitejs/plugin-rsc`, `react-server-dom-webpack`) as devDependencies 3. Adds `"type": "module"` to package.json 4. Renames CJS config files (e.g., `postcss.config.js` → `.cjs`) to avoid ESM conflicts 5. Adds `dev:vinext` and `build:vinext` scripts to package.json @@ -58,29 +60,30 @@ If `vinext init` succeeds, skip to Phase 4 (Verify). If it fails or the user pre Use this as a fallback when `vinext init` doesn't work or the user wants full control. -### 3a. Replace packages +### 3a. Add vinext + Vite 8 dependencies ```bash # Example with npm: -npm uninstall next npm install vinext -npm install -D vite +npm install -D vite@^8 @vitejs/plugin-react # App Router only: -npm install -D @vitejs/plugin-rsc +npm install -D @vitejs/plugin-rsc react-server-dom-webpack ``` -### 3b. Update scripts +Keep `next` installed until you've validated the vinext path. The recommended migration flow is additive first, cleanup second. + +### 3b. Add or update scripts -Replace all `next` commands in `package.json` scripts: +Prefer parallel vinext scripts first so you can compare both runtimes side by side: -| Before | After | Notes | -| ------------ | -------------- | -------------------------- | -| `next dev` | `vinext dev` | Dev server with HMR | -| `next build` | `vinext build` | Production build | -| `next start` | `vinext start` | Local production server | -| `next lint` | `vinext lint` | Delegates to eslint/oxlint | +| Script | Command | Notes | +| -------------- | ---------------------- | ------------------------------------- | +| `dev:vinext` | `vite dev --port 3001` | Dev server with HMR | +| `build:vinext` | `vite build` | Production build | +| `start:vinext` | `vinext start` | Local production server for built app | +| `lint:vinext` | `vinext lint` | Delegates to eslint/oxlint | -Preserve flags: `next dev --port 3001` → `vinext dev --port 3001`. +Once the vinext path is working, you can decide whether to swap your default `dev` / `build` scripts over. ### 3c. Convert to ESM @@ -176,6 +179,7 @@ Nitro auto-detects the platform in most CI/CD environments, so the preset is oft ## Phase 5: Verify 1. Run `vinext dev` to start the development server + Or `npm run dev:vinext` if you added parallel scripts. 2. Confirm the server starts without errors 3. Navigate key routes and check functionality 4. Report the result to the user — if errors occur, share full output diff --git a/.agents/skills/migrate-to-vinext/references/compatibility.md b/.agents/skills/migrate-to-vinext/references/compatibility.md index 610ee7960..af9b2a0be 100644 --- a/.agents/skills/migrate-to-vinext/references/compatibility.md +++ b/.agents/skills/migrate-to-vinext/references/compatibility.md @@ -1,5 +1,7 @@ # Compatibility Reference +These notes assume a Vite 8 migration path for new projects. vinext still keeps Vite 7 compatibility, but Vite 8 is the preferred baseline. + ## Supported next/\* Imports All of these resolve automatically to vinext shims. Do not rewrite imports in application code. diff --git a/.agents/skills/migrate-to-vinext/references/config-examples.md b/.agents/skills/migrate-to-vinext/references/config-examples.md index 91aac0ca1..148c4f9de 100644 --- a/.agents/skills/migrate-to-vinext/references/config-examples.md +++ b/.agents/skills/migrate-to-vinext/references/config-examples.md @@ -1,6 +1,6 @@ # Vite Config Examples -These examples stay minimal on purpose. If you add custom build tuning on Vite 8, prefer `oxc`, `optimizeDeps.rolldownOptions`, and `build.rolldownOptions` / `worker.rolldownOptions` over older `esbuild` and `build.rollupOptions` settings. +These examples stay minimal on purpose. New migrations should target Vite 8. If you add custom build tuning on Vite 8, prefer `oxc`, `optimizeDeps.rolldownOptions`, and `build.rolldownOptions` / `worker.rolldownOptions` over older `esbuild` and `build.rollupOptions` settings. ## Pages Router — Local Development @@ -192,8 +192,13 @@ Nitro auto-detects the platform in most CI/CD environments, so the `NITRO_PRESET | Flag | Description | | -------------------- | ---------------------------------------- | +| `--env ` | Deploy using `wrangler.jsonc` `env.name` | | `--preview` | Deploy to preview environment | | `--name ` | Override worker name | | `--skip-build` | Skip build step (deploy existing output) | | `--dry-run` | Generate config without deploying | +| `--prerender-all` | Pre-render discovered routes after build | | `--experimental-tpr` | Enable Traffic-aware Pre-Rendering | +| `--tpr-coverage` | Set TPR traffic coverage target | +| `--tpr-limit` | Cap the number of TPR pages | +| `--tpr-window` | Set the TPR analytics lookback window | diff --git a/.agents/skills/migrate-to-vinext/references/troubleshooting.md b/.agents/skills/migrate-to-vinext/references/troubleshooting.md index c956b8164..edefaf83f 100644 --- a/.agents/skills/migrate-to-vinext/references/troubleshooting.md +++ b/.agents/skills/migrate-to-vinext/references/troubleshooting.md @@ -7,13 +7,15 @@ | `ERR_REQUIRE_ESM` or `require() of ES Module` | Project missing `"type": "module"` | Add `"type": "module"` to package.json | | `module.exports` syntax error in config file | CJS config loaded as ESM | Rename `.js` config to `.cjs` (e.g., `postcss.config.js` → `postcss.config.cjs`) | | `Cannot find module '@vitejs/plugin-rsc'` | App Router project missing RSC plugin | `npm install -D @vitejs/plugin-rsc` | -| `Cannot find module 'vite'` | Vite not installed | `npm install -D vite` | +| `Cannot find module 'vite'` | Vite not installed | `npm install -D vite@^8` | | `vinext: command not found` | vinext not installed or not in PATH | Install vinext: `npm install vinext`, then run via `npx vinext` or package.json scripts | | RSC environment crash on dev start | Native Node module (sharp, satori) loaded in RSC env | vinext auto-stubs these in production; in dev, ensure these are only imported in server code behind dynamic `import()` | | `ASSETS binding not found` | wrangler.jsonc missing assets config | Add `"assets": { "not_found_handling": "none" }` to wrangler.jsonc | ## Vite 8 Migration Notes +Vite 8 is the preferred path for new vinext migrations. Keep Vite 7 only when you are working around a specific compatibility issue in an existing project. + - **Symptom:** deprecation warnings for `esbuild`, `optimizeDeps.esbuildOptions`, or `build.rollupOptions`. **Cause:** Vite 8 now defaults to Oxc and Rolldown. **Fix:** Prefer `oxc`, `optimizeDeps.rolldownOptions`, and `build.rolldownOptions` / `worker.rolldownOptions` in custom Vite config. @@ -83,7 +85,7 @@ imported from \node_modules.pnpm\validator@13.15.26\node_modules\validator\es\li After migration, confirm: -- [ ] `vinext dev` starts without errors +- [ ] `vinext dev` or `npm run dev:vinext` starts without errors - [ ] Home page renders correctly - [ ] Dynamic routes resolve (e.g., `/posts/[id]`) - [ ] API routes respond (Pages Router) or route handlers respond (App Router) diff --git a/AGENTS.md b/AGENTS.md index b1d593d23..ea4cac521 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,15 +17,16 @@ vinext reimplements the Next.js API surface using Vite, with Cloudflare Workers ### Commands ```bash -pnpm test # Vitest — full suite (~2 min, serial) -pnpm test tests/routing.test.ts # Run a single test file (~seconds) -pnpm test tests/shims.test.ts tests/link.test.ts # Run specific files -pnpm run test:e2e # Playwright E2E tests (all projects, use PLAYWRIGHT_PROJECT= to target one) -pnpm run check # Format, lint, and type checks -pnpm run lint # Lint only (type-aware oxlint) -pnpm run fmt # oxfmt (format) -pnpm run fmt:check # oxfmt (check only, no writes) -pnpm run build # Build the vinext package (via vp pack) +vp install # Install/update deps through Vite+ +vp test run # Vitest — full suite (~2 min, serial) +vp test run tests/routing.test.ts # Run a single test file (~seconds) +vp test run tests/shims.test.ts tests/link.test.ts # Run specific files +vp run test:e2e # Playwright E2E tests (all 7 projects, use PLAYWRIGHT_PROJECT= to target one) +vp run check # Format, lint, and type checks +vp run lint # Lint only (type-aware oxlint) +vp run fmt # oxfmt (format) +vp run fmt:check # oxfmt (check only, no writes) +vp run build # Build the vinext package (via vp pack) ``` ### Project Structure @@ -128,7 +129,7 @@ gh search code "must export" --repo vercel/next.js --filename "*.test.*" --limit **Always run targeted tests, not the full suite.** The full Vitest suite takes ~2 minutes because test files run serially (to avoid Vite deps optimizer cache races). Running the full suite during development wastes time, especially when multiple agents are working on the repo simultaneously. -**Prefer `vp` for day-to-day local work.** The `pnpm` scripts above still work, but current repo workflow and CI debugging usually use the direct Vite+ commands: +**Prefer `vp` for day-to-day local work.** The repo still exposes a few wrapper scripts via `vp run ...`, but current repo workflow and CI debugging usually use the direct Vite+ commands: ```bash vp check tests/app-router.test.ts @@ -141,16 +142,16 @@ vp run vinext#build ```bash # Run a single test file (fast — seconds, not minutes) -pnpm test tests/routing.test.ts +vp test run tests/routing.test.ts # Run a few related files -pnpm test tests/shims.test.ts tests/link.test.ts +vp test run tests/shims.test.ts tests/link.test.ts # Run all nextjs-compat tests -pnpm test tests/nextjs-compat/ +vp test run tests/nextjs-compat/ # Run tests matching a name pattern -pnpm test -t "middleware" +vp test run -t "middleware" ``` **Which test files to run** depends on what you changed: @@ -165,7 +166,7 @@ pnpm test -t "middleware" | Build/deploy | `tests/deploy.test.ts`, `tests/build-optimization.test.ts` | | Next.js compat features | `tests/nextjs-compat/` (the relevant file) | -**Let CI run the full suite.** The full `pnpm test` and all 5 Playwright E2E projects run in CI on every PR. You do not need to run the full suite locally before pushing. CI will catch any cross-cutting regressions. +**Let CI run the full suite.** The full `vp test run` and all 7 Playwright E2E projects run in CI on every PR. You do not need to run the full suite locally before pushing. CI will catch any cross-cutting regressions. **When to run the full suite locally:** Only if you're making a broad change that touches shared infrastructure (e.g., the Vite plugin's `resolveId` hook, virtual module generation, or the test helpers themselves). Even then, consider pushing and letting CI do it. @@ -185,7 +186,7 @@ If Next.js and vinext should behave differently (defense-in-depth, Cloudflare-sp - `entries/app-rsc-entry.ts` — App Router dev (generates the RSC entry) - `server/dev-server.ts` — Pages Router dev - `server/prod-server.ts` — Pages Router production (handles middleware, routing, SSR directly) -- `cloudflare/worker-entry.ts` — Cloudflare Workers entry +- `server/app-router-entry.ts` — default Cloudflare/App Router worker entry The App Router production server delegates to the built RSC entry, so it inherits fixes from `entries/app-rsc-entry.ts`. But the Pages Router production server has its own middleware/routing/SSR logic that must be updated separately. @@ -193,7 +194,7 @@ When fixing a bug in any of these files, check whether the same bug exists in th ### Debugging -- **Dev server logs**: Run `npx vite dev` in a fixture directory +- **Dev server logs**: Run `vp dev` in a fixture directory - **RSC streaming issues**: Context is often cleared before stream consumption — check AsyncLocalStorage usage - **Module resolution**: Vite has separate module instances for RSC/SSR/client environments @@ -220,6 +221,8 @@ The `examples/` directory contains real-world Next.js apps ported to run on vine | `benchmarks` | Performance benchmarks | `benchmarks.vinext.workers.dev` | | `hackernews` | HN clone (App Router, RSC) | `hackernews.vinext.workers.dev` | +The repo also keeps non-deployed/reference examples such as `app-router-nitro`, `fumadocs-docs-template`, and `tpr-demo` under `examples/`. + #### Adding a New Example 1. Create a directory under `examples/` with a `package.json` (use `"vinext": "workspace:*"`) @@ -325,7 +328,7 @@ If a Node built-in does the job, use it. Only reach for a dependency when the bu - **NEVER push directly to main.** Always create a feature branch and open a PR, even for small fixes. This ensures CI runs before changes are merged and provides a review checkpoint. -- **Branch protection is enabled on main.** Required checks: Check, Vitest, Playwright E2E. Pushing directly to main bypasses these protections and can introduce regressions. +- **Branch protection is enabled on main.** Wait for the full CI fanout to pass before merging: Check, Vitest (unit + integration), create-next-app, and E2E. - **NEVER use `gh pr merge --admin`.** The `--admin` flag bypasses branch protection checks entirely. If merge is blocked, investigate why — don't force it through. A blocked merge usually means a required check failed or is still running. @@ -334,7 +337,7 @@ If a Node built-in does the job, use it. Only reach for a dependency when the bu 2. Make changes and commit 3. Push branch: `git push -u origin fix/descriptive-name` 4. Open PR via `gh pr create` - 5. Wait for CI to pass — all required checks (Check, Vitest, Playwright E2E) must be green + 5. Wait for CI to pass — Check, Vitest (unit + integration), create-next-app, and E2E should all be green 6. Merge via `gh pr merge --squash --delete-branch` 7. If merge is blocked, check which status check failed and fix it — do not bypass with `--admin` @@ -344,7 +347,7 @@ If a Node built-in does the job, use it. Only reach for a dependency when the bu 3. Push, fix CI, and re-request review 4. Rebase the next stacked branch after each merge -- **Use `/bigbonk` after meaningful updates on stacked refactor PRs.** That is the normal re-review loop for this repo once a PR has been rebased or a review comment has been addressed. +- **Use `/bigbonk` after meaningful updates on stacked refactor PRs.** That is the normal deep re-review loop once a PR has been rebased or a review comment has been addressed. Use `/bonk` or `@ask-bonk` when you want a lighter follow-up pass. ### CI for External Contributors @@ -352,7 +355,7 @@ CI is split into safe checks (no secrets) and deploy previews (requires secrets) **Safe CI (`ci.yml`)** runs for all PRs after first-time contributor approval: -- Check, Vitest, Playwright E2E +- Check, Vitest (unit + integration), create-next-app, and Playwright E2E - Uses zero secrets and read-only permissions - First-time contributors need one manual approval, then subsequent PRs run automatically @@ -360,19 +363,13 @@ CI is split into safe checks (no secrets) and deploy previews (requires secrets) - The entire workflow is skipped for fork PRs via a job-level `if` condition - Cloudflare employees should push branches to the main repo (not fork), so previews deploy automatically -- For fork PRs, a maintainer can comment `/deploy-preview` to trigger the deploy (see `deploy-preview-command.yml`) - -**`/deploy-preview` slash command** (`deploy-preview-command.yml`): - -- Triggered by commenting `/deploy-preview` on any PR -- Restricted to org members, collaborators, and repo owners via `author_association` -- Builds all examples, deploys previews, runs smoke tests, and posts preview URLs +- Fork PRs currently do not have a checked-in preview-deploy override workflow; if preview URLs are needed, mirror the changes onto a same-repo branch first When modifying CI workflows, keep these rules in mind: - `ci.yml` must never use secrets. It runs untrusted code from forks. - `deploy-examples.yml` must skip entirely for fork PRs. Don't remove the job-level `if` guard. -- The `/deploy-preview` slash command gates secret usage behind the `author_association` check. +- The Bonk workflows (`bonk.yml`, `bigbonk.yml`) gate write-capable review automation behind the `author_association` check. --- @@ -570,7 +567,7 @@ Vite+ automatically detects and wraps the underlying package manager such as pnp - upgrade - Update `vp` itself to the latest version -These commands map to their corresponding tools. For example, `vp dev --port 3000` runs Vite's dev server and works the same as Vite. `vp test` runs JavaScript tests through the bundled Vitest. The version of all tools can be checked using `vp --version`. This is useful when researching documentation, features, and bugs. +This repo treats Vite 8 as the preferred baseline. Keep Vite 7 compatibility when it is cheap, but new repo-facing docs, scripts, and examples should assume Vite 8 + latest Vite+ by default. The version of all tools can be checked using `vp --version`, which is useful when researching docs, features, and bugs. ## Common Pitfalls @@ -579,11 +576,11 @@ These commands map to their corresponding tools. For example, `vp dev --port 300 - **Running scripts:** Vite+ commands take precedence over `package.json` scripts. If there is a `test` script defined in `scripts` that conflicts with the built-in `vp test` command, run it using `vp run test`. - **Do not install Vitest, Oxlint, Oxfmt, or tsdown directly:** Vite+ wraps these tools. They must not be installed directly. You cannot upgrade these tools by installing their latest versions. Always use Vite+ commands. - **Use Vite+ wrappers for one-off binaries:** Use `vp dlx` instead of package-manager-specific `dlx`/`npx` commands. -- **Import JavaScript modules from `vite-plus`:** Instead of importing from `vite` or `vitest`, all modules should be imported from the project's `vite-plus` dependency. For example, `import { defineConfig } from 'vite-plus';` or `import { expect, test, vi } from 'vite-plus/test';`. You must not install `vitest` to import test utilities. +- **Prefer `vite-plus` in repo-owned configs, tests, and docs examples:** Use `vite-plus` / `vite-plus/test` by default when you are editing the repo's own config and test surfaces. When touching vinext runtime code or generated/public-facing config templates that intentionally target Vite's public API, importing from `vite` is still expected. - **Static checks:** Prefer `vp check` as the default validation command. It runs formatting, linting, and type checks together, and `vp lint --type-aware` works when you need lint-only feedback. ## Review Checklist for Agents - [ ] Run `vp install` after pulling remote changes and before getting started. -- [ ] Run `vp check` and `vp test` to validate changes. +- [ ] Run `vp run check` plus the targeted `vp test run ...` commands relevant to your change. diff --git a/CLAUDE.md b/CLAUDE.md index c31706425..47dc3e3d8 120000 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1 +1 @@ -AGENTS.md +AGENTS.md \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e33818e3..840abd626 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,16 +8,16 @@ We use [OpenCode](https://opencode.ai) with Claude Opus 4.6, set to max thinking ## Before you open a PR -1. **Run the test suite.** `pnpm test` runs Vitest. `pnpm run test:e2e` runs Playwright. +1. **Run the relevant test suite.** Use targeted `vp test run ...` commands for the files you touched, and `vp run test:e2e` when you changed browser behavior. 2. **Add tests for new functionality.** Unit tests go in `tests/*.test.ts`. Browser-level tests go in `tests/e2e/`. -3. **Run the static checks.** `pnpm run check` runs formatting, linting, and type checks via Vite+. +3. **Run the static checks.** `vp run check` runs formatting, linting, and type checks via Vite+. 4. **Read `AGENTS.md`.** It has the architecture context, key gotchas, and development workflow that will save you (and your AI) time. ## AI code review -Every PR goes through AI code review. When you open a PR, a contributor with write access will request a review from **BigBonk** (Claude Opus 4.6, max thinking mode). External contributors can't trigger this directly. +Every PR goes through AI code review. When you open a PR, a contributor with write access will request a review from **BigBonk** (Claude Opus 4.6, max thinking mode) by triggering the repo's review automation. External contributors can't trigger this directly. -Our process is to iterate on BigBonk's feedback until there are no unresolved comments. That doesn't mean you have to accept every suggestion verbatim, but we've found it to be very good at finding real problems and very useful for debugging this codebase. Expect multiple review rounds on larger PRs. +Our process is to iterate on BigBonk's feedback until there are no unresolved comments. That doesn't mean you have to accept every suggestion verbatim, but we've found it to be very good at finding real problems and very useful for debugging this codebase. Expect multiple review rounds on larger PRs. Maintainers often use `/bigbonk` for the thorough pass and `/bonk` for quicker follow-ups. **Our bias is towards merging.** This is a new project with known gaps, and we're trying to fill them as fast as possible. We want to get PRs in, not block them. If your contribution moves things forward, we'll work with you to get it landed. diff --git a/README.md b/README.md index c9f52ed0c..b79cd602d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The skill handles compatibility checking, dependency installation, config genera ### Or do it manually ```bash -npm install -D vinext vite @vitejs/plugin-react +npm install -D vinext vite@^8 @vitejs/plugin-react ``` If you're using the App Router, also install: @@ -34,21 +34,21 @@ If you're using the App Router, also install: npm install -D @vitejs/plugin-rsc react-server-dom-webpack ``` -Replace `next` with `vinext` in your scripts: +Add parallel vinext scripts while you validate the migration: ```json { "scripts": { - "dev": "vinext dev", - "build": "vinext build", - "start": "vinext start" + "dev:vinext": "vite dev --port 3001", + "build:vinext": "vite build", + "start:vinext": "vinext start" } } ``` ```bash -vinext dev # Development server with HMR -vinext build # Production build +npm run dev:vinext # Development server with HMR +npm run build:vinext vinext deploy # Build and deploy to Cloudflare Workers ``` @@ -70,7 +70,7 @@ Your existing `pages/`, `app/`, `next.config.js`, and `public/` directories work Options: `-p / --port `, `-H / --hostname `, `--turbopack` (accepted, no-op). -`vinext deploy` options: `--preview`, `--env `, `--name `, `--skip-build`, `--dry-run`, `--experimental-tpr`. +`vinext deploy` options: `--preview`, `--env `, `--name `, `--skip-build`, `--dry-run`, `--prerender-all`, `--experimental-tpr`, `--tpr-coverage `, `--tpr-limit `, `--tpr-window `. `vinext init` options: `--port ` (default: 3001), `--skip-check`, `--force`. @@ -91,7 +91,7 @@ npx vinext init This will: 1. Run `vinext check` to scan for compatibility issues -2. Install `vite`, `@vitejs/plugin-react`, and App Router-only deps (`@vitejs/plugin-rsc`, `react-server-dom-webpack`) as devDependencies +2. Install `vite` (latest Vite 8 by default), `@vitejs/plugin-react`, and App Router-only deps (`@vitejs/plugin-rsc`, `react-server-dom-webpack`) as devDependencies 3. Rename CJS config files (e.g. `postcss.config.js` -> `.cjs`) to avoid ESM conflicts 4. Add `"type": "module"` to `package.json` 5. Add `dev:vinext` and `build:vinext` scripts to `package.json` @@ -99,7 +99,7 @@ This will: The migration is non-destructive -- your existing Next.js setup continues to work alongside vinext. It does not modify `next.config`, `tsconfig.json`, or any source files, and it does not remove Next.js dependencies. -vinext supports both Vite 7 and Vite 8. If you bring custom Vite config or plugins from an older setup, note that Vite 8 now defaults to Rolldown, Oxc, Lightning CSS, and a newer browser baseline. Prefer `oxc`, `optimizeDeps.rolldownOptions`, and `build.rolldownOptions` over older `esbuild` and `build.rollupOptions` knobs, and override `build.target` if you still need older browsers. If a dependency only breaks on Vite 8 because of stricter CommonJS default import handling, fix the import or use `legacy.inconsistentCjsInterop: true` as a temporary escape hatch. See the [Vite 8 migration guide](https://vite.dev/guide/migration). +New migrations should target Vite 8. vinext still keeps Vite 7 compatibility for older setups, but the docs and examples below assume the Vite 8 defaults (Rolldown, Oxc, Lightning CSS, and the newer browser baseline). Prefer `oxc`, `optimizeDeps.rolldownOptions`, and `build.rolldownOptions` over older `esbuild` and `build.rollupOptions` knobs, and override `build.target` if you still need older browsers. If a dependency only breaks on Vite 8 because of stricter CommonJS default import handling, fix the import or use `legacy.inconsistentCjsInterop: true` as a temporary escape hatch. See the [Vite 8 migration guide](https://vite.dev/guide/migration). ```bash npm run dev:vinext # Start the vinext dev server (port 3001) @@ -402,7 +402,8 @@ These are deployed to Cloudflare Workers and updated on every push to `main`: | Pages Router (minimal) | Minimal Pages Router on Workers | [pages-router-cloudflare.vinext.workers.dev](https://pages-router-cloudflare.vinext.workers.dev) | | RealWorld API | REST API routes example | [realworld-api-rest.vinext.workers.dev](https://realworld-api-rest.vinext.workers.dev) | | Benchmarks Dashboard | Build performance tracking over time (D1-backed) | [benchmarks.vinext.workers.dev](https://benchmarks.vinext.workers.dev) | -| App Router + Nitro | App Router deployed via Nitro (multi-platform) | [examples/app-router-nitro](examples/app-router-nitro) | + +Additional checked-in examples that are not part of the auto-deploy matrix live under [`examples/`](/Users/steve/.codex/worktrees/8805/vinext/examples), including `app-router-nitro`, `fumadocs-docs-template`, and `tpr-demo`. ## API coverage @@ -649,23 +650,24 @@ tests/ *.test.ts # Vitest unit + integration tests nextjs-compat/ # Tests ported from Next.js test suite fixtures/ # Test apps (pages-basic, app-basic, ecosystem libs) - e2e/ # Playwright E2E tests (5 projects) + e2e/ # Playwright E2E tests (7 projects) -examples/ # Deployed demo apps (see Live Examples above) +examples/ # Demo apps (some auto-deployed, some local/reference) ``` ## Tests ```bash -pnpm test # Vitest unit + integration tests -pnpm run test:e2e # Playwright E2E tests (5 projects) -pnpm run check # Format, lint, and type checks -pnpm run lint # Lint only (type-aware oxlint) -pnpm run fmt # Formatting (oxfmt) -pnpm run fmt:check # Check formatting without writing +vp test run --project unit # Vitest unit tests +vp test run --project integration # Vitest integration tests +vp run test:e2e # Playwright E2E tests (7 projects; set PLAYWRIGHT_PROJECT= to target one) +vp run check # Format, lint, and type checks +vp run lint # Lint only (type-aware oxlint) +vp run fmt # Formatting (oxfmt) +vp run fmt:check # Check formatting without writing ``` -E2E tests cover Pages Router (dev + production), App Router (dev), and both routers on Cloudflare Workers via `wrangler dev`. +E2E tests cover Pages Router (dev + production), App Router (dev), and both routers on Cloudflare Workers and Cloudflare-flavored dev flows. The [Vercel App Router Playground](https://github.com/vercel/next-app-router-playground) runs on vinext as an integration test — see it live at [app-router-playground.vinext.workers.dev](https://app-router-playground.vinext.workers.dev). @@ -676,17 +678,17 @@ If you're working from the repo instead of installing from npm: ```bash git clone https://github.com/cloudflare/vinext.git cd vinext -pnpm install -pnpm run build +vp install +vp run build ``` -This builds the vinext package to `packages/vinext/dist/` via `vp pack`. For active development, use `pnpm --filter vinext run dev` to run `vp pack --watch`. +This builds the vinext package to `packages/vinext/dist/` via `vp pack`. For active development, use `vp run vinext#dev` to run `vp pack --watch`. -To use it against an external Next.js app, link the built package: +To use it against an external Next.js app, install the built package from your local checkout: ```bash # From your Next.js project directory: -pnpm link /path/to/vinext/packages/vinext +vp add "file:/path/to/vinext/packages/vinext" ``` Or add it to your `package.json` as a file dependency: @@ -699,7 +701,7 @@ Or add it to your `package.json` as a file dependency: } ``` -vinext has peer dependencies on `react ^19.2.4`, `react-dom ^19.2.4`, and `vite ^7.0.0 || ^8.0.0`. Then replace `next` with `vinext` in your scripts and run as normal. +vinext has peer dependencies on `react >=19.2.0`, `react-dom >=19.2.0`, and `vite ^7.0.0 || ^8.0.0`. New projects should prefer Vite 8. ## Contributing @@ -707,9 +709,9 @@ This project is experimental and under active development. Issues and PRs are we ### CI -When you open a PR, CI (check, Vitest, Playwright E2E) runs automatically. First-time contributors need one manual approval from a maintainer, then subsequent PRs run without intervention. +When you open a PR, CI (Check, Vitest unit + integration, create-next-app, and Playwright E2E) runs automatically. First-time contributors need one manual approval from a maintainer, then subsequent PRs run without intervention. -Deploy previews (building and deploying examples to Cloudflare Workers) only run for branches pushed to the main repo. If you're a Cloudflare employee, push your branch to the main repo instead of forking, and previews deploy automatically. For fork PRs, a maintainer can comment `/deploy-preview` to trigger the deploy and post preview URLs. +Deploy previews (building and deploying examples to Cloudflare Workers) only run for same-repo branches today. Fork PRs still get the safe CI workflow, but they do not get preview deploys unless the changes are mirrored onto a branch in the main repo. ### Reporting bugs From b87c76642f416708db241141b747e355c62b69aa Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Sun, 22 Mar 2026 14:57:19 -0500 Subject: [PATCH 2/3] docs: clarify additive migration guidance --- .agents/skills/migrate-to-vinext/SKILL.md | 4 ++-- README.md | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.agents/skills/migrate-to-vinext/SKILL.md b/.agents/skills/migrate-to-vinext/SKILL.md index ade817563..3a3564e90 100644 --- a/.agents/skills/migrate-to-vinext/SKILL.md +++ b/.agents/skills/migrate-to-vinext/SKILL.md @@ -70,11 +70,11 @@ npm install -D vite@^8 @vitejs/plugin-react npm install -D @vitejs/plugin-rsc react-server-dom-webpack ``` -Keep `next` installed until you've validated the vinext path. The recommended migration flow is additive first, cleanup second. +Keep `next` installed until you've validated the vinext path. This mirrors `vinext init`, which adds vinext scripts without overwriting the existing Next.js ones. ### 3b. Add or update scripts -Prefer parallel vinext scripts first so you can compare both runtimes side by side: +Mirror `vinext init`: add parallel vinext scripts first so you can validate the vinext path without losing the existing Next.js commands: | Script | Command | Notes | | -------------- | ---------------------- | ------------------------------------- | diff --git a/README.md b/README.md index b79cd602d..341b018fe 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ If you're using the App Router, also install: npm install -D @vitejs/plugin-rsc react-server-dom-webpack ``` -Add parallel vinext scripts while you validate the migration: +`vinext init` adds side-by-side vinext scripts instead of overwriting your existing Next.js commands. If you're migrating manually, mirror that flow first: ```json { @@ -52,6 +52,8 @@ npm run build:vinext vinext deploy # Build and deploy to Cloudflare Workers ``` +Once the vinext path looks good, you can swap your default `dev` / `build` scripts over if you want vinext to take over completely. + vinext auto-detects your `app/` or `pages/` directory, loads `next.config.js`, and configures Vite automatically. No `vite.config.ts` required for basic usage. Your existing `pages/`, `app/`, `next.config.js`, and `public/` directories work as-is. Run `vinext check` first to scan for known compatibility issues, or use `vinext init` to [automate the full migration](#migrating-an-existing-nextjs-project). @@ -391,7 +393,7 @@ See the [Nitro deployment docs](https://v3.nitro.build/deploy) for the full list ## Live examples -These are deployed to Cloudflare Workers and updated on every push to `main`: +Most of these are deployed to Cloudflare Workers and updated on every push to `main`. The Nitro example is kept here as a checked-in multi-platform deployment reference: | Example | Description | URL | | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | @@ -402,8 +404,9 @@ These are deployed to Cloudflare Workers and updated on every push to `main`: | Pages Router (minimal) | Minimal Pages Router on Workers | [pages-router-cloudflare.vinext.workers.dev](https://pages-router-cloudflare.vinext.workers.dev) | | RealWorld API | REST API routes example | [realworld-api-rest.vinext.workers.dev](https://realworld-api-rest.vinext.workers.dev) | | Benchmarks Dashboard | Build performance tracking over time (D1-backed) | [benchmarks.vinext.workers.dev](https://benchmarks.vinext.workers.dev) | +| App Router + Nitro | App Router deployed via Nitro (multi-platform) | [examples/app-router-nitro](/Users/steve/.codex/worktrees/8805/vinext/examples/app-router-nitro) | -Additional checked-in examples that are not part of the auto-deploy matrix live under [`examples/`](/Users/steve/.codex/worktrees/8805/vinext/examples), including `app-router-nitro`, `fumadocs-docs-template`, and `tpr-demo`. +Additional checked-in examples that are not part of the auto-deploy matrix live under [`examples/`](/Users/steve/.codex/worktrees/8805/vinext/examples), including `fumadocs-docs-template` and `tpr-demo`. ## API coverage From 31741f8a7547a4b6fc71acc59ce6819bbce58e9b Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Sun, 22 Mar 2026 19:56:06 -0500 Subject: [PATCH 3/3] docs: add fresh worktree bootstrap guidance --- AGENTS.md | 19 +++++++++++++++++++ README.md | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ea4cac521..63a897fec 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,6 +29,24 @@ vp run fmt:check # oxfmt (check only, no writes) vp run build # Build the vinext package (via vp pack) ``` +### Fresh Worktree Bootstrap + +**Every new Codex session / git worktree should run this bootstrap before doing feature work.** Assume a fresh worktree does **not** have installed dependencies or a local Next.js reference clone yet. + +```bash +vp install + +if [ ! -d .nextjs-ref/.git ]; then + git clone --depth 1 --single-branch --branch canary https://github.com/vercel/next.js.git .nextjs-ref +else + git -C .nextjs-ref pull --ff-only +fi +``` + +- `vp install` is required before running tests or builds in a fresh worktree. +- `.nextjs-ref/` is gitignored and lives per worktree, so clone or update it in each new session. +- Do this bootstrap before searching the Next.js source or test suite. + ### Project Structure ``` @@ -582,5 +600,6 @@ This repo treats Vite 8 as the preferred baseline. Keep Vite 7 compatibility whe ## Review Checklist for Agents - [ ] Run `vp install` after pulling remote changes and before getting started. +- [ ] Ensure `.nextjs-ref/` exists in this worktree; clone it if missing, `git -C .nextjs-ref pull --ff-only` if present. - [ ] Run `vp run check` plus the targeted `vp test run ...` commands relevant to your change. diff --git a/README.md b/README.md index 341b018fe..1270865c7 100644 --- a/README.md +++ b/README.md @@ -404,9 +404,9 @@ Most of these are deployed to Cloudflare Workers and updated on every push to `m | Pages Router (minimal) | Minimal Pages Router on Workers | [pages-router-cloudflare.vinext.workers.dev](https://pages-router-cloudflare.vinext.workers.dev) | | RealWorld API | REST API routes example | [realworld-api-rest.vinext.workers.dev](https://realworld-api-rest.vinext.workers.dev) | | Benchmarks Dashboard | Build performance tracking over time (D1-backed) | [benchmarks.vinext.workers.dev](https://benchmarks.vinext.workers.dev) | -| App Router + Nitro | App Router deployed via Nitro (multi-platform) | [examples/app-router-nitro](/Users/steve/.codex/worktrees/8805/vinext/examples/app-router-nitro) | +| App Router + Nitro | App Router deployed via Nitro (multi-platform) | [examples/app-router-nitro](examples/app-router-nitro) | -Additional checked-in examples that are not part of the auto-deploy matrix live under [`examples/`](/Users/steve/.codex/worktrees/8805/vinext/examples), including `fumadocs-docs-template` and `tpr-demo`. +Additional checked-in examples that are not part of the auto-deploy matrix live under [`examples/`](examples/), including `fumadocs-docs-template` and `tpr-demo`. ## API coverage