Skip to content

feat(cli): support local templates via create.templates in vp create#1777

Merged
fengmk2 merged 38 commits into
mainfrom
fix/create-picker-local-generators
Jun 10, 2026
Merged

feat(cli): support local templates via create.templates in vp create#1777
fengmk2 merged 38 commits into
mainfrom
fix/create-picker-local-generators

Conversation

@fengmk2

@fengmk2 fengmk2 commented Jun 7, 2026

Copy link
Copy Markdown
Member

Summary

Adds first-class support for local templates in vp create, declared in create.templates in a monorepo's vite.config.ts (the design agreed with @cpojer). This replaces the earlier implicit package.json keyword detection.

What it does

  • create.templates config: declare local templates as { name, description, template } entries (reusing the org manifest schema and validator). Inside a monorepo, the vp create picker lists these entries; selecting one (or vp create <name>) resolves the entry's template specifier through the normal discovery path.
  • Auto-registration: vp create vite:generator scaffolds a Bingo generator and registers it in create.templates automatically (idempotent, preserving any defaultTemplate), so it appears in the picker with no manual edit.
  • Generator template fixes: runs directly via node bin/index.ts (.ts imports, bingo 0.9.3, zod v3 aligned with bingo, Node >=22.18.0). bingo/zod move from the repo root into vite-plus devDependencies.
  • Source of truth: Vite+ no longer infers templates from package.json keywords. A bingo dependency is only a run hint (auto --skip-requests). A declared template without a bin errors clearly instead of falling through to npm create-<name>.
  • Monorepo git: adding a package to an existing monorepo no longer prompts to initialize git.

Behavior change

vp create <workspace-package> runs as a template only when that package is declared in create.templates; otherwise it resolves as an npm create-<name> package as before.

Docs and tests

create.templates config reference, the Code Generators guide, and both create RFCs are updated. Adds unit tests, a create-generator-monorepo snap (scaffold, auto-registration, and run end to end), and global snap updates.


Note

Medium Risk
Changes how workspace package names resolve in vp create (breaking if teams relied on unregistered local packages) and modifies config via AST splice plus read-modify-write of vite.config.ts.

Overview
Introduces create.templates in vite.config.ts as the explicit registry for monorepo-local vp create templates (name, description, template). In a monorepo, the picker lists these entries and vp create <name> resolves to each entry’s template specifier; workspace package names no longer run as templates unless registered (otherwise behavior stays create-<name> on npm).

vp create vite:generator now auto-appends an idempotent entry (preserving defaultTemplate) via new registerLocalTemplate, backed by Rust replaceJsonConfig to overwrite an existing top-level config key instead of duplicating it with merge. Local runs use discoverTemplate with stricter bin resolution, bingo-only --skip-requests, and output co-located under the generator’s parent dir; missing bin errors instead of npm fallthrough.

Removes keyword-based template inference and isTemplatePackage; skips git init when adding packages inside an existing monorepo. Generator scaffold updates (bingo 0.9.3, zod v3, direct node bin/index.ts). Docs, RFCs, CONTRIBUTING local-validation notes, and snap/unit tests added or updated.

Reviewed by Cursor Bugbot for commit a9a2fc3. Configure here.

@fengmk2 fengmk2 self-assigned this Jun 7, 2026
@netlify

netlify Bot commented Jun 7, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit a7a04ad
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a28fa69606cdf00084cb6a8

@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

✅ Staging deployment successful!

Preview: https://viteplus-staging.void.app/
Commit: a7a04ad

@fengmk2 fengmk2 changed the title fix(cli): offer local generator packages in the create template picker fix(cli): make local Bingo generators discoverable and runnable in vp create Jun 7, 2026
@fengmk2 fengmk2 changed the title fix(cli): make local Bingo generators discoverable and runnable in vp create fix(cli): make local Bingo generators work in vp create Jun 7, 2026
@fengmk2 fengmk2 added test: e2e Auto run e2e tests test: install-e2e run vite install e2e test test: create-e2e Run `vp create` e2e tests labels Jun 7, 2026
@fengmk2

This comment was marked as resolved.

@fengmk2

This comment was marked as resolved.

cursor[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

fengmk2 added 12 commits June 8, 2026 13:39
Workspace packages scaffolded by `vp create vite:generator` carry the
`bingo-template` keyword and are flagged as template packages during
workspace detection, but the interactive `vp create` picker only listed
built-in templates, so local generators were never offered.

`getInitialTemplateOptions` now accepts the workspace packages and
appends an option per template package (after the built-ins, monorepo
only), with the package name as value and its description as hint.
Selecting one flows into the existing `discoverTemplate` local-package
path, which already runs bingo templates via their bin entry with
`--skip-requests`.
Add a Code Generators section to the create guide covering how to
scaffold a generator with `vp create vite:generator`, run it from the
interactive picker or by package name, and customize the template.
…project

Explain how the global vp resolves the project-local vite-plus first,
how to link a checkout into a test project with pnpm link, and when
pnpm bootstrap-cli is needed for Rust global CLI changes.
The generator template scaffolded by `vp create vite:generator` crashed
with ERR_MODULE_NOT_FOUND whenever the generator was run: its bin
imported '../src/template.js' (a tsc-style specifier), but vp create
executes the template directly with `node bin/index.ts`, where Node
type stripping does not remap .js specifiers to .ts files.

- import '../src/template.ts' directly and cast for runTemplateCLI,
  whose parameter type is wider than createTemplate's return under TS 6
- update bingo to 0.9.3 (latest) in the catalog and the template
- align the catalog zod with bingo, which depends on zod 3 and
  introspects schemas via zod 3 internals; the generator template is
  the only zod consumer in the repo
- move bingo/zod to vite-plus devDependencies: they are the generator
  template's dependencies and snap tests resolve modules from the CLI
  package's node_modules
- bump the template engines to >=22.18.0, the first Node version that
  runs .ts files without the --experimental-strip-types flag
- add a unit test that runs the template bin directly with node
The only generator snap test covered the error path outside a monorepo.
The new create-generator-monorepo case scaffolds a generator inside a
monorepo with vite:generator, locks the template package.json contract
into the snapshot, runs the generator through `vp create my-generator`
(the path that crashed before the template fix), and verifies the
generated files.
pnpm 11 records the link as a vite-plus link: override in
pnpm-workspace.yaml (or pnpm.overrides in package.json), so it
survives later installs instead of being restored by them.
The bingo-template keyword / bingo dependency check was duplicated
between discoverWorkspacePackages and discoverTemplate. Both now use a
single isBingoTemplate helper so the detection criteria live in one
place. Also drop the unreachable '' fallback for the picker hint, the
package path is always set.
Spinner frames such as '◒  Preparing local Git repository...' appear in
snap output intermittently depending on timing, while the final
'◇'/'◆' state line is stable. Normalize them away in
replaceUnstableOutput and regenerate the create-generator-monorepo
snapshot without the transient frame.
The case scaffolds a generator and prints its package.json, which now
carries bingo ^0.9.3 and engines >=22.18.0.
A workspace package carrying the vite-plus-template keyword but no bin
field was offered by the create picker, then discoverTemplate silently
fell through to expandCreateShorthand and would install and run the
unrelated npm package create-<name>. The fallthrough predates the
picker, but the picker made it reachable interactively.

- extract isTemplatePackage() so the picker and discovery share the
  template classification
- discoverTemplate now throws a clear error for a template package
  without a bin entry instead of falling through to npm
- use || for the picker hint so an empty description falls back to the
  package path
- strip clack spinner frames at end-of-output without a trailing
  newline
- document why the catalog pins zod to v3 (bingo introspects schemas
  via zod 3 internals)
Running a local generator in a monorepo with multiple parent dirs (e.g.
apps/* and tools/*) placed the generated package under apps/ because
inferParentDir only recognized the literal vite:generator builtin and
fell back to the default app rule for a local generator's package name.

inferParentDir now resolves a local template package to its own parent
directory, so a generator under tools/ scaffolds its output into tools/
rather than apps/. The create-generator-monorepo snap fixture gains an
apps/* parent so it actually exercises the multi-parent case the
tools-only fixture missed.

Closes review comment on #1777.
@fengmk2 fengmk2 force-pushed the fix/create-picker-local-generators branch from 676352f to 0080cda Compare June 8, 2026 05:46
fengmk2 added 2 commits June 8, 2026 15:42
Extract findLocalPackage so discoverTemplate and inferParentDir resolve
a template specifier to a workspace package the same way. Also tighten
the inferParentDir test to exercise the isTemplatePackage guard with a
non-template package instead of re-checking the default rule.
…nd harden multi-bin resolution

Two robustness fixes for local template packages now that they are
directly selectable from the create picker:

- isTemplatePackage (picker visibility) now requires the vite-plus-template
  or bingo-template keyword. A plain `bingo` dependency no longer surfaces a
  normal workspace package as a template; it remains an execution hint in
  isBingoTemplate (controls --skip-requests), separating 'is this offered'
  from 'how is it run'.
- discoverTemplate resolves a package's bin via resolveLocalBinPath: a single
  bin (string or one-entry object) is used directly, a multi-bin package
  prefers the entry named after the package (scoped or unscoped), and an
  ambiguous multi-bin package with no matching entry throws a clear error
  instead of silently picking the first key.
@fengmk2

This comment was marked as resolved.

@fengmk2

This comment was marked as resolved.

cursor[bot]

This comment was marked as resolved.

@fengmk2

This comment was marked as resolved.

@fengmk2

This comment was marked as resolved.

Comment thread packages/cli/src/create/register-template.ts
Comment thread packages/cli/src/create/register-template.ts
registerLocalTemplate found the config via a trimmed list (.ts/.js/.mjs),
so a monorepo whose only config was vite.config.mts/.cts/.cjs got a stray
new vite.config.ts with the create.templates block, leaving the real
config untouched. Reuse the canonical config finder: add findViteConfig
(all six extensions) to resolve-vite-config.ts and call it, dropping
register-template's private list.

Closes the bugbot wrong-config-target report.
@fengmk2

This comment was marked as resolved.

@fengmk2

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

Three review fixes:
- Do not re-match an org-resolved specifier against local create.templates:
  an org entry { name: 'web', template: 'component' } no longer redirects to
  a local entry also named 'component' (guard the local match with a
  resolvedByOrg flag).
- Do not clobber the create block when the root config exists but cannot be
  evaluated: getConfiguredCreate gains throwOnReadError so registration aborts
  instead of overwriting with only the new entry. The generator is already
  scaffolded, so bin.ts warns and points at the manual edit rather than
  failing the whole create.
- Write the merge temp file to a unique OS-temp path instead of a fixed
  .vite-plus-create-register.json in the workspace, which could overwrite a
  user file of that name.
@fengmk2

This comment was marked as resolved.

@fengmk2

fengmk2 commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

Comment thread packages/cli/src/create/bin.ts Outdated
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Generator registration formatted a hardcoded vite.config.ts in a separate
step, which both missed other extensions (.mts/.cts/.cjs) and formatted the
wrong file. Drop the dedicated format: registerLocalTemplate now returns the
path it wrote, and the existing monorepo format pass formats that file
alongside the new package, so the right config is always reformatted and no
separate step is needed.
@fengmk2

fengmk2 commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit a9a2fc3. Configure here.

@cpojer cpojer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it. We need to raise awareness of how useful this can be to large company monorepos.

fengmk2 added 2 commits June 10, 2026 11:12
…ution

Code-review fixes for the create.templates flow:

- Replace replace_json_config with upsert_json_config: only direct config
  objects are edited (a create key inside a nested function return, e.g. an
  inline plugin's config() hook, is never spliced), shorthand `create`
  properties are replaced in place, the key is inserted when missing, and
  unsupported shapes report updated: false instead of being corrupted by the
  merge fallback
- registerLocalTemplate throws when the config shape is unsupported so the
  caller warns with the add-it-by-hand snippet instead of reporting a
  registration that never happened; it also warns when a same-name entry
  already points at a different template
- vp create exits cleanly on a malformed create.templates (no stack dump),
  warns when the root config cannot be evaluated instead of silently letting
  a registered name fall through to an npm package, and no longer aborts the
  whole create when the scaffolded generator's package.json is unreadable
- getConfiguredDefaultTemplate rethrows CreateConfigSchemaError so a valid
  defaultTemplate is not silently dropped in standalone projects
- discoverTemplate errors when a by-name entry matches no workspace package
  instead of dlx-running the same-named npm package
- inferParentDir only co-locates for create.templates resolutions, so an npm
  template colliding with a workspace package name keeps the apps rule
- WorkspacePackage.path is normalized to forward slashes, fixing co-location
  under multi-segment parent dirs on Windows
- VITE_CONFIG_FILES matches Vite's DEFAULT_CONFIG_FILES order so registration
  reads and writes the same file when multiple configs exist
- create.templates entry names starting with vite: are rejected at validation
  to keep builtins from being shadowed
- register-template tests run in self-contained os.tmpdir workspaces with a
  stubbed vite-plus instead of inside the repo's node_modules
Comment thread packages/cli/src/resolve-vite-config.ts
fengmk2 added 2 commits June 10, 2026 13:46
WorkspacePackage.path is now normalized to forward slashes, so the
Windows-only path.join expectation no longer applies.
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​bingo@​0.7.0 ⏵ 0.9.385 +110084 +192 +6100

View full report

@fengmk2 fengmk2 merged commit 0315153 into main Jun 10, 2026
93 checks passed
@fengmk2 fengmk2 deleted the fix/create-picker-local-generators branch June 10, 2026 06:23
Brooooooklyn added a commit that referenced this pull request Jun 12, 2026
main removed WorkspacePackage.isTemplatePackage (#1777 follow-up in
0315153) and added tools specs importing the deleted
@voidzero-dev/vite-plus-test wrapper; drop the stale property from the
migration spec literals and import the tools specs from vitest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Brooooooklyn added a commit that referenced this pull request Jun 12, 2026
main removed WorkspacePackage.isTemplatePackage (#1777 follow-up in
0315153) and added tools specs importing the deleted
@voidzero-dev/vite-plus-test wrapper; drop the stale property from the
migration spec literals and import the tools specs from vitest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Brooooooklyn added a commit that referenced this pull request Jun 15, 2026
main removed WorkspacePackage.isTemplatePackage (#1777 follow-up in
0315153) and added tools specs importing the deleted
@voidzero-dev/vite-plus-test wrapper; drop the stale property from the
migration spec literals and import the tools specs from vitest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@fengmk2 fengmk2 mentioned this pull request Jun 17, 2026
fengmk2 added a commit that referenced this pull request Jun 17, 2026
Release vite-plus v0.2.0.

Vite+ now consumes upstream Vitest directly (no wrapper), raises the
minimum supported Node.js version to 22.18.0, and ships corepack and
devEngines support.

### Highlights

- **`vp test` now runs upstream Vitest directly (breaking)**: Vite+ used
to ship `@voidzero-dev/vite-plus-test`, a rebundled copy of Vitest that
lagged upstream releases. That package is removed; `vp test` now runs
the real upstream `vitest`, which is installed automatically as a
dependency of `vite-plus` (you no longer add `vitest` or `@vitest/*`
yourself, and `vite` still resolves to `@voidzero-dev/vite-plus-core`
via package-manager overrides). Your `import ... from 'vite-plus/test'`
code keeps working unchanged and `vp migrate` updates existing projects
([#1588](#1588)), by
@Brooooooklyn
- **Minimum supported Node.js version raised to `^22.18.0 || >=24.11.0`
(breaking)**: Node 20 reached end-of-life and the bundled tsdown already
required `^22.18.0`, so the published engines range now matches what `vp
pack` can actually deliver; `vp exec` / `vp run` / `vp dlx` reject
projects resolving an older Node with the existing incompatibility error
([#1813](#1813)), by
@fengmk2
- **Corepack now works under Vite+**: `corepack` is a default `vp env
setup` shim, resolved managed-global, then Node-bundled (Node <= 24),
then auto-installed (Node 25+, which dropped corepack); `corepack
enable` / `disable` land their pnpm/yarn launchers on PATH and
Vite+-owned shims are restored if corepack replaces them
([#1808](#1808)), by
@fengmk2
- **devEngines support for runtime and package-manager selection**:
Vite+ reads `devEngines.runtime` (ranked above `engines.node`) and
`devEngines.packageManager`; auto-pin and `vp migrate` write
`devEngines.packageManager`, `vp env pin` / `unpin` target
`devEngines.runtime`, and `vp env doctor` reports conflicts instead of
silently resolving them
([#1760](#1760)), by
@fengmk2

### Features

- `vp pm approve-builds`: forward to npm's new `approve-scripts` /
`deny-scripts` (npm >= 11.16.0) instead of the previous no-op, matching
`pnpm approve-builds` / `bun pm trust`; mixed approve+deny is rejected
with actionable guidance and npm's advisory-only caveat is surfaced
([#1733](#1733)), by
@fengmk2
- `vp create`: support local monorepo templates declared in
`create.templates` in `vite.config.ts`; `vp create vite:generator`
scaffolds a Bingo generator and auto-registers it in the picker,
replacing the old package.json-keyword inference
([#1777](#1777)), by
@fengmk2
- `vp create`: detect direct dependencies whose build scripts the
package manager gated (e.g. native builds like `better-sqlite3`) and act
on them; prompt to approve each (default off) interactively, point at
`vp pm approve-builds` non-interactively, or build them with
`--approve-builds`
([#1828](#1828)), by
@fengmk2
- `vp config`: add `--no-hooks` and `--no-agent` opt-outs to skip
git-hook installation and coding-agent instruction updates
([#1842](#1842)), by
@leno23
- `vp list -g`: sort the global package list output so entries appear in
a stable order
([#1748](#1748)), by
@liangmiQwQ
- Upgrade upstream dependencies: rolldown `1.0.3 -> 1.1.1`, tsdown
`0.22.1 -> 0.22.3`, oxlint `1.67.0 -> 1.70.0`, oxfmt `0.52.0 -> 0.55.0`,
vitest `4.1.8 -> 4.1.9`, and the oxc toolchain `0.133.0 -> 0.136.0`
([#1749](#1749),
[#1767](#1767),
[#1812](#1812),
[#1834](#1834),
[#1855](#1855)), by
@voidzero-guard[bot]

### Fixes & Enhancements

- Security: resolve open Rust Dependabot advisories by bumping
transitive `openssl` `0.10.76 -> 0.10.80` (`openssl-sys` `0.9.112 ->
0.9.116`), fixing five high-severity rust-openssl issues (buffer
overflows in key derivation, AES key wrap, and digest finalization; an
unchecked PSK/cookie trampoline length leaking adjacent memory; and
OCSP-responder undefined behavior:
[GHSA-pqf5-4pqq-29f5](GHSA-pqf5-4pqq-29f5),
[GHSA-8c75-8mhr-p7r9](GHSA-8c75-8mhr-p7r9),
[GHSA-ghm9-cr32-g9qj](GHSA-ghm9-cr32-g9qj),
[GHSA-hppc-g8h3-xhp3](GHSA-hppc-g8h3-xhp3),
[GHSA-xp3w-r5p5-63rr](GHSA-xp3w-r5p5-63rr)),
and drop the unmaintained, unsound `libyml`
([GHSA-gfxp-f68g-8x78](GHSA-gfxp-f68g-8x78),
high) by removing dead `serde_yml` code
([#1742](#1742)), by
@fengmk2
- Security (docs site): update `mermaid` `11.13.0 -> 11.15.0` to fix
improper `classDef` sanitization in state diagrams that allowed HTML
injection
([CVE-2026-41149](https://nvd.nist.gov/vuln/detail/CVE-2026-41149) /
[GHSA-ghcm-xqfw-q4vr](GHSA-ghcm-xqfw-q4vr),
medium severity; `<script>` tags are stripped so it does not reach XSS)
([#1745](#1745)), by
@renovate[bot]
- `vp check --fix` / `vp staged`: create/migrate now wrap inline Vite
`plugins: [...]` arrays with `lazyPlugins(...)` so plugin factories
aren't eagerly executed (and don't hang on open handles) during
lint/format/check config loading
([#1752](#1752)), by
@jong-kyung
- `vp migrate`: complete pending migration work for projects that
already have `vite-plus` installed (scripts, imports, tsconfig types,
ESLint/Prettier, legacy hooks, package-manager settings) instead of
treating `vite-plus` as migration-complete; fully migrated projects stay
idempotent
([#1821](#1821)), by
@jong-kyung
- `vp create` / `vp migrate`: detect shorthand `fmt,` / `lint,` config
keys so a duplicate inline block is no longer injected
([#1843](#1843)), by
@fengmk2
- IDE oxlint/oxfmt wrappers: set `VP_COMMAND` so `lazyPlugins()` skips
framework plugins during LSP config reads, preventing a stray
`.svelte-kit` (and similar) directory at the monorepo root
([#1764](#1764)), by
@jong-kyung
- `vp lint` / `vp run -r lint` on Windows: keep the absolute `tsgolint`
path for workspace lint runs instead of downgrading it to a wrong
cwd-relative path
([#1758](#1758)), by
@semimikoh
- oxlint wrapper: set the `tsgolint` path so type-aware lint resolves it
([#1811](#1811)), by
@jong-kyung
- `vp install -g`: use a unique backup directory and treat stale-backup
cleanup as best-effort so a locked Windows binary no longer fails an
otherwise successful reinstall
([#1753](#1753)), by
@fengmk2
- `vp install -g`: remove stale managed binary shims when a reinstalled
package drops a bin from its `package.json#bin`
([#1765](#1765)), by
@liangmiQwQ
- `vp create --git`: surface git's actual stdout/stderr when the initial
commit fails instead of always blaming `user.name` / `user.email`
([#1819](#1819)), by
@fengmk2
- `vp create vite:generator`: reject `--git` / `--no-git`, since adding
a generator to an existing monorepo does not initialize git
([#1788](#1788)), by
@jong-kyung
- Global CLI: harden `find_system_tool` against a self-exec loop (skip
the running executable's own bin directory) and fix two
`vite_global_cli` tests that could hang
([#1820](#1820)), by
@fengmk2
- CLI help: unify alias display
([#1832](#1832)), show
supported `run` options
([#1797](#1797)), show
`--fail-if-no-match` in `exec` help
([#1798](#1798)), add the
`implode` documentation link
([#1796](#1796)), and
handle nested-command typo help
([#1803](#1803)), by
@jong-kyung

### Docs

- Document `vp create` opt-out options
([#1790](#1790)), by
@jong-kyung
- Document `vp upgrade` options
([#1847](#1847)), by
@jong-kyung
- Align the config overview with the sidebar
([#1846](#1846)), by
@jong-kyung
- Sync the documented command lists with the help output
([#1850](#1850)), by
@jong-kyung
- Clarify lazy plugin side effects
([#1841](#1841)), by
@leno23
- Add JongKyung's X profile
([#1844](#1844)) and
update Christoph's X profile
([#1845](#1845)) on the
team page, by @jong-kyung

### Refactor

- Remove the CLI tips system; the shortcuts it printed on `vp install`
are already covered by the help system and added unnecessary complexity
([#1799](#1799)), by
@cpojer

### Chore

- Re-enable Renovate dependency updates with a targeted ignore-list
([#1744](#1744)), by
@fengmk2
- Keep generated NAPI bindings during upgrade-deps
([#1759](#1759)), by
@fengmk2
- Remove the `vite_glob` dependency from vite-plus
([#1763](#1763)), by
@wan9chi
- Keep `sync-remote` from churning `pnpm-workspace.yaml` (dedupe
`minimumReleaseAgeExclude`, preserve comments)
([#1787](#1787)), by
@fengmk2
- Make unix `just test` runnable
([#1755](#1755)), by
@situ2001
- CI: reuse `just lint` and `just test` as the single source of truth
([#1809](#1809)), pin
`cargo-zigbuild` to a git rev to fix the aarch64-musl link failure
([#1815](#1815)), and keep
upgrade-deps green when rolldown bumps oxc
([#1833](#1833)), by
@fengmk2
- Update Rust to nightly-2026-06-10
([#1725](#1725)), typos to
v1.47.1 / v1.47.2
([#1772](#1772),
[#1775](#1775)), GitHub
Actions ([#1778](#1778),
[#1829](#1829)), and npm
packages ([#1779](#1779)),
by @renovate[bot]
- Bump `oxc-project/setup-node` to v1.3.1
([#1792](#1792)), by
@Boshen
- Refresh trusted stack stats on the docs homepage
([#1786](#1786),
[#1837](#1837)), by
@voidzero-guard[bot]

### Bundled Versions

| Tool | Version | Source |
| --- | --- | --- |
| vite | `8.0.16` |
[`f94df87`](vitejs/vite@f94df87)
|
| rolldown | `1.1.1` |
[`d7f919c`](rolldown/rolldown@d7f919c)
|
| tsdown | `0.22.3` | [npm](https://npmx.dev/package/tsdown/v/0.22.3) |
| vitest | `4.1.9` | [npm](https://npmx.dev/package/vitest/v/4.1.9) |
| oxlint | `1.70.0` | [npm](https://npmx.dev/package/oxlint/v/1.70.0) |
| oxlint-tsgolint | `0.23.0` |
[npm](https://npmx.dev/package/oxlint-tsgolint/v/0.23.0) |
| oxfmt | `0.55.0` | [npm](https://npmx.dev/package/oxfmt/v/0.55.0) |

### Upgrading from 0.1.24 to 0.2.0

This release has two breaking changes. For most projects the upgrade is
`vp upgrade`, bump the project's `vite-plus`, then `vp migrate`.

#### 1. Update the CLI

```bash
vp upgrade
```

#### 2. Node.js 20 is no longer supported

The minimum supported Node.js version is now `^22.18.0 || >=24.11.0`
(Node 20 reached end-of-life). If you are still on Node 20:

- Check your version: `node --version` (or `vp env doctor`)
- Move to a supported release: `vp env pin 22.18.0` (or a newer LTS), or
update your `.node-version` / `devEngines.runtime`

`vp exec` / `vp run` / `vp dlx` now refuse to run against a project that
resolves Node < 22.18.0.

#### 3. Vitest is now upstream (the wrapper is gone)

`@voidzero-dev/vite-plus-test` has been removed; Vite+ consumes upstream
`vitest` directly. Bump `vite-plus` first, then migrate:

```bash
vp update vite-plus --latest    # project's vite-plus -> 0.2.0 (ignores the old range, updates the lockfile); monorepo: add -r
vp migrate                      # local vite-plus is now 0.2.0, so the new migration runs
```

`vp update --latest` re-resolves `vite-plus` to the newest release
regardless of the old semver range, so the lockfile cannot pin you back
to 0.1.24. The project's local `vite-plus` is then 0.2.0, and since the
global `vp` delegates `migrate` to the project's local install, `vp
migrate` runs the new migration.

- Your `import { vi, ... } from 'vite-plus/test'` code is unchanged. `vp
migrate` rewrites any leftover `vitest` / `@vitest/*` imports and
normalizes stale `vitest: npm:@voidzero-dev/vite-plus-test@*` aliases.
- You no longer add `vitest` or `@vitest/*` yourself; they arrive
transitively through `vite-plus`.

### New Contributors

Welcome to our new contributor @situ2001! 🎉

**Full Changelog**:
v0.1.24...v0.2.0

---

Merging this PR will trigger the release workflow.

---------

Co-authored-by: voidzero-guard[bot] <278573678+voidzero-guard[bot]@users.noreply.github.com>
Co-authored-by: MK <fengmk2@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test: create-e2e Run `vp create` e2e tests test: e2e Auto run e2e tests test: install-e2e run vite install e2e test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants