Vite+ is the web toolchain behind vp: Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, Vite Task, runtime and package-manager workflows, and project creation/migration.
This guide applies to this repository; CLAUDE.md points here. For changes to the guidance shipped to user projects, use packages/cli/AGENTS.md and packages/cli/src/utils/agent.ts. Leave those files unchanged for root-guide tasks.
- CLI routing:
packages/cli/src/bin.tsdispatches JS commands;packages/cli/binding/src/lib.rsandpackages/cli/binding/src/cli/mod.rshandle local NAPI commands. Global routing starts atcrates/vp_global_cli/src/main.rsandcrates/vp_global_cli/src/cli.rs. Compare global and local paths for routing bugs. - Package managers and runtimes: use
crates/vp_pm_cli/andcrates/vp_js_runtime/. The Windows shim trampoline lives incrates/vp_trampoline/, outside the Cargo workspace. - Config loading: compare the static extractor with the JS fallback in
packages/cli/src/resolve-vite-config.ts. - Migration: follow the migrator instructions when changing
vp migrate; use migration rules for expected behavior. - Bundled tools and exports: use CLI bundling and core bundling. Test resolution starts at
packages/cli/src/resolve-test.ts;packages/cli/build.tsgenerates test API shims. - Testing a local build in a project: follow CONTRIBUTING.md for linking and installation. For
vp migrate/vp create, use the local registry inpackages/tools/src/local-npm-registry.ts, which also serves PTY fixtures and ecosystem tests. - Product documentation: start at
README.mdand the VitePress site indocs/guide/anddocs/config/. - Setup and build commands: use
CONTRIBUTING.md,justfile, andpackage.json. Start withjust initfor initial setup. Repository lint, format, and test configuration lives invite.config.ts; TypeScript settings live intsconfig.json.
- Distinguish built-ins from tasks:
vp testexecutes upstream Vitest;vp run testexecutes a script or configured task namedtest.vpris shorthand forvp run. Inspect command surfaces withvp help/vp <command> --help, and bundled versions withvp --version. - Keep task configuration under
runinvite.config.ts; do not introducevite-task.json. Existingpackage.jsonscripts arevp runtargets without caching by default. Userun.tasksfor explicit command configuration, default caching, dependencies, or input/environment tracking. A task name must occur in only one of these files. See the run guide and run configuration. - Keep public test imports on
vite-plus/test*, which wraps upstreamvitestand@vitest/browser*. Do not recreatepackages/testor@voidzero-dev/vite-plus-test. - Vite Task crates are git dependencies in
Cargo.toml; there is no localcrates/vt. Do not runcargo test -p vthere. - Use
vp_shared::VpDirsfor Vite+ directory roots. Seecrates/vp_shared/src/dirs.rsandcrates/vp_shared/src/dirs/resolution.rs. Call sites must not construct category paths or readVP_HOMEorXDG_*directly. - Follow
.clippy.tomlfor Rust restrictions and replacements. Usecrates/vp_shared/src/output.rsfor user-facing output; command output that can be piped must useprint_and_flushor another broken-pipe-safe helper instead ofprint!orprintln!. Enableclippy::print_stdoutin migrated modules so CI prevents direct stdout macros from returning. Usecrates/vp_shared/src/env_config.rsfor test-scoped environment configuration. Seecrates/vp_command/src/lib.rsforvt_pathusage. - For TypeScript CLI output, use
packages/cli/src/utils/terminal.tsand match the surrounding command style. - Keep changes scoped to the task and leave unrelated tracked and untracked files alone. Prefer source references over duplicated instructions in this guide.
Prefer local fixtures or mock servers for tests that depend on external services. Use real network requests only when they are necessary to verify the behavior under test, and explain that need in the test. Reuse existing test infrastructure, preserve behavioral coverage, and keep mutable state isolated between cases.
For behavior changes, find nearby tests before editing and add or update coverage in the same area. Choose checks for the changed layer:
| Change | Validation |
|---|---|
| Documentation / agent guidance | Verify referenced paths, commands, and links; git diff --check -- <files> |
| TypeScript / JS CLI | vp check, pnpm test:unit, and focused package tests |
| Rust CLI / crates | just check, just test, just lint |
| CLI output / interactions | Focused tests and just snapshot-test <filter>; review snapshot diffs |
| Global CLI | pnpm bootstrap-cli and vp --version for installed end-to-end checks; just snapshot-test-global <filter> for global snapshots |
| Release / build | just build |
| Full pre-merge check | pnpm bootstrap-cli && pnpm test && git status |
Validate vp check, lint, format, and type-check changes end-to-end: bundled-tool routing can hide config drift. Use vp check --fix only when you intend to apply formatting or lint fixes. Documentation-only changes need no unrelated test suites.
Write new CLI tests, including interactive flows, in crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/. Read the snapshot runner instructions before adding cases; they define snapshots.toml, CLI flavors, vpt helpers, and prompt milestones. See the RFC for design rationale.
- Steps are argv arrays without an implicit shell. Use
vpthelpers instead of coreutils for portable file operations. - For package-manager cases, prefer the runner's local registry, shared registry fixtures, and response cache over new public-registry requests. Keep package-manager caches isolated per case, and refresh recorded fixtures only through the explicit maintenance command.
- For changes to network use or scheduling, compare request counts and elapsed time with the same cases, worker count, and initial cache state. Do not remove assertions or share mutable case state to improve speed.
- Local-flavor cases require a fresh
packages/cli/dist. Usejust snapshot-test-global <filter>when no JS build is available. - For intended snapshot changes, run
UPDATE_SNAPSHOTS=1 just snapshot-test <filter>. Review and commit the recorded.mdfiles with the fixture; mismatches fail the run and produce.md.newfiles.
Prefer a stack of small PRs for work with separable layers. Use the gh-stack extension or github.com; stacks require branches in this repository, so use standalone PRs from forks. Follow CONTRIBUTING.md for submission and commit-signing requirements.