Skip to content
Back to skills

Vite Agents Review

ASecurity

Use when reviewing Vite configuration, validating a Vite project, checking for common mistakes, or auditing Vite code before deployment. Prevents shipping insecure envPrefix settings, wrong bundler options for the target version, and known anti-patterns. Covers config correctness, plugin hook signatures, HMR patterns, version-specific API usage, build optimization, environment variable security, SSR configuration, and anti-pattern detection. Keywords: review, validation, checklist, audit, ant...

  • 5 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 10, 2026
developmenttypescriptgoreactvuenodegitapisecurityperformance

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add OpenAEC-Foundation/OpenAEC-Workspace-Composer --skill vite-agents-review --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Vite Agents Review?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Vite Agents Review
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/openaec-foundation-vite-agents-review/badge)](https://www.skillsdirectory.com/skills/openaec-foundation-vite-agents-review)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: vite-agents-review
description: >
  Use when reviewing Vite configuration, validating a Vite project, checking
  for common mistakes, or auditing Vite code before deployment.
  Prevents shipping insecure envPrefix settings, wrong bundler options for the
  target version, and known anti-patterns.
  Covers config correctness, plugin hook signatures, HMR patterns,
  version-specific API usage, build optimization, environment variable
  security, SSR configuration, and anti-pattern detection.
  Keywords: review, validation, checklist, audit, anti-pattern, envPrefix,
  plugin hooks, security, SSR, build optimization.
license: MIT
compatibility: "Designed for Claude Code. Requires Vite 6.x, 7.x, or 8.x."
metadata:
  author: OpenAEC-Foundation
  version: "1.0"
---

# vite-agents-review

## How to Use This Skill

Run every check in order. Mark each item PASS or FAIL. A single FAIL in a critical area (Security, Configuration) blocks deployment. Fix all FAILs before approving code.

---

## 1. Configuration Checks

| # | Check | Expected State | Common Failure |
|---|-------|---------------|----------------|
| C-01 | `defineConfig()` wraps config export | ALWAYS use `defineConfig()` for type safety and IDE support | Raw object export loses autocomplete and type checking |
| C-02 | Bundler options match target version | v8: `build.rolldownOptions` / v6-v7: `build.rollupOptions` | Using `rollupOptions` on v8 triggers deprecation; using `rolldownOptions` on v6 is invalid |
| C-03 | Transform config matches target version | v8: `oxc` option / v6-v7: `esbuild` option | Using `esbuild` on v8 is deprecated; using `oxc` on v6 is invalid |
| C-04 | `envPrefix` is NOT empty string | MUST be `'VITE_'` or a non-empty custom prefix | Setting `envPrefix: ''` exposes ALL environment variables to client code |
| C-05 | `appType` matches usage pattern | `'spa'` for single-page, `'mpa'` for multi-page, `'custom'` for SSR/middleware | Wrong `appType` causes missing HTML middleware or unwanted SPA fallback |
| C-06 | `build.target` is appropriate | Use `'baseline-widely-available'` (v7+/v8) or explicit browser list | Setting `'esnext'` for production breaks older browsers |
| C-07 | `loadEnv()` used in config, NOT `import.meta.env` | ALWAYS use `loadEnv(mode, root, prefix)` inside config files | `import.meta.env` is undefined during config resolution |
| C-08 | Conditional config uses function form | `defineConfig(({ command, mode }) => ({...}))` | Forgetting `command`/`mode` parameters leads to static config for all modes |

---

## 2. Plugin Checks

| # | Check | Expected State | Common Failure |
|---|-------|---------------|----------------|
| P-01 | Plugin is a factory function returning object | ALWAYS export a function, NEVER a plain object | Plain objects prevent configuration via options parameter |
| P-02 | Plugin object has `name` property | ALWAYS include `name` string on plugin object | Missing `name` makes errors/warnings untraceable |
| P-03 | `config` hook returns partial config or mutates | Return object is deep-merged; mutations are applied directly | Returning a full config object overwrites user settings |
| P-04 | `configResolved` stores config for later hooks | Store resolved config in closure variable | Accessing `config` parameter outside the hook lifecycle |
| P-05 | `configureServer` adds middleware correctly | Use `server.middlewares.use()` for pre-middleware; return function for post-middleware | Adding post-middleware directly instead of returning a function |
| P-06 | `transformIndexHtml` uses correct order property | `order: 'pre'` for before HTML processing, `order: 'post'` (default) for after | Using deprecated `enforce` property (removed in v7) |
| P-07 | `handleHotUpdate` returns correct type | Return `ModuleNode[]` to narrow updates, `[]` to skip, or `void` for default | Returning wrong type causes HMR failures |
| P-08 | `enforce` property used correctly | `'pre'` runs before core plugins, `'post'` runs after build plugins | Omitting `enforce` when ordering matters causes transform conflicts |
| P-09 | Virtual modules use correct prefix convention | User-facing: `virtual:` prefix; internal: `\0` prefix on resolved ID | Missing `\0` prefix lets other plugins process the virtual module |
| P-10 | `moduleParsed` hook NOT relied upon in dev | NEVER depend on `moduleParsed` during development | This hook is skipped in dev for performance — code silently fails |
| P-11 | v8: `moduleType: 'js'` set in load/transform for non-JS | ALWAYS set `moduleType: 'js'` when returning non-JS content | Rolldown cannot process content without explicit module type |

---

## 3. HMR Checks

| # | Check | Expected State | Common Failure |
|---|-------|---------------|----------------|
| H-01 | `import.meta.hot` guard wraps ALL HMR code | ALWAYS wrap in `if (import.meta.hot) { ... }` | HMR code ships to production, increasing bundle size |
| H-02 | `accept(` has no space before parenthesis | Write `import.meta.hot.accept(` exactly | Vite static analysis fails with `accept (` — HMR silently breaks |
| H-03 | `hot.data` mutated via properties, NEVER reassigned | `import.meta.hot.data.key = value` | `import.meta.hot.data = { key: value }` silently fails |
| H-04 | `accept()` called BEFORE `invalidate()` | ALWAYS call `accept()` first to establish HMR boundary | Calling `invalidate()` without `accept()` has no effect |
| H-05 | `dispose()` used for cleanup of side effects | Register cleanup in `import.meta.hot.dispose(cb)` | Timers, event listeners, WebSocket connections leak across updates |
| H-06 | `prune()` used for module removal cleanup | Register in `import.meta.hot.prune(cb)` when module may be removed | Resources persist after module is no longer imported |

---

## 4. Environment Variable Checks

| # | Check | Expected State | Common Failure |
|---|-------|---------------|----------------|
| E-01 | Only `VITE_*` vars accessed in client code | ALWAYS prefix client-exposed vars with `VITE_` | Non-prefixed vars are `undefined` in `import.meta.env` |
| E-02 | No secrets in `VITE_*` variables | NEVER put API keys, tokens, or passwords in `VITE_*` vars | Client code exposes all `VITE_*` values in browser source |
| E-03 | TypeScript: `ImportMetaEnv` interface defined | Declare in `src/vite-env.d.ts` with `/// <reference types="vite/client" />` | Missing types cause `import.meta.env.VITE_*` to be `any` |
| E-04 | `loadEnv()` used in config, NOT `import.meta.env` | `const env = loadEnv(mode, process.cwd(), '')` | `import.meta.env` is not available during config resolution |
| E-05 | `.env.local` files added to `.gitignore` | ALWAYS gitignore `.env*.local` files | Local secrets committed to version control |

---

## 5. Build Checks

| # | Check | Expected State | Common Failure |
|---|-------|---------------|----------------|
| B-01 | `build.target` matches deployment environment | Set explicit target or use `'baseline-widely-available'` | Default `'esnext'` (if set) breaks older browsers |
| B-02 | Sourcemaps not accidentally exposed in production | Use `'hidden'` or `false` for production deployments | `build.sourcemap: true` exposes source code via `.map` files |
| B-03 | CSS code splitting enabled | Keep `build.cssCodeSplit: true` (default) | Disabling creates single CSS file, hurting load performance |
| B-04 | Library mode: `name` set for UMD/IIFE builds | ALWAYS provide `build.lib.name` when formats include UMD or IIFE | Missing `name` causes build error for global variable |
| B-05 | Library mode: peer deps externalized | Add framework deps to `rolldownOptions.external` (v8) or `rollupOptions.external` (v6-v7) | Bundling React/Vue into library doubles framework in consumer app |
| B-06 | Library mode: `package.json` exports configured | Set `main`, `module`, and `exports` fields | Consumers cannot resolve the library entry point |
| B-07 | `build.minify` appropriate for target | v8 default: `'oxc'` for client; v6-v7: `'esbuild'`; SSR: `false` | Using Terser without installing it, or minifying SSR output |
| B-08 | Chunk size warnings addressed | Investigate chunks exceeding `build.chunkSizeWarningLimit` (500 KiB) | Ignoring warnings leads to slow page loads |

---

## 6. SSR Checks

| # | Check | Expected State | Common Failure |
|---|-------|---------------|----------------|
| S-01 | Middleware mode sets `appType: 'custom'` | ALWAYS pair `server: { middlewareMode: true }` with `appType: 'custom'` | Default SPA fallback interferes with custom server routing |
| S-02 | `ssr.noExternal` configured for deps needing transforms | Add deps with non-ESM code or Vite-processed imports to `ssr.noExternal` | Untransformed CSS imports or JSX crash Node.js at runtime |
| S-03 | `ssrFixStacktrace` in error handlers | ALWAYS call `vite.ssrFixStacktrace(e)` in SSR catch blocks | Stack traces point to transformed code instead of source files |
| S-04 | `import.meta.env.SSR` used for conditional logic | Use `import.meta.env.SSR` to branch server/client code | Using `typeof window` checks that fail in edge runtimes |
| S-05 | SSR build uses `--ssr` flag | Build with `vite build --ssr src/entry-server.js` | Building SSR entry without `--ssr` flag bundles as client code |
| S-06 | SSR manifest generated for preload hints | Add `--ssrManifest` to client build command | Missing preload directives degrade perceived load performance |

---

## 7. Security Checks

| # | Check | Expected State | Common Failure |
|---|-------|---------------|----------------|
| X-01 | `envPrefix` not set to empty string | NEVER use `envPrefix: ''` | Exposes ALL env vars (including `DB_PASSWORD`, `SECRET_KEY`) to client |
| X-02 | `server.fs.strict` not disabled without reason | Keep `server.fs.strict: true` (default) | Disabling allows dev server to serve any file on the machine |
| X-03 | `server.allowedHosts` configured for non-localhost | Set explicit host list when exposing dev server to network | DNS rebinding attacks can access dev server resources |
| X-04 | No secrets in client-exposed code | NEVER put credentials in `VITE_*` env vars, `define`, or client source | All client code is readable in browser DevTools |
| X-05 | Production sourcemaps restricted | Use `build.sourcemap: 'hidden'` or `false` | Public `.map` files expose full source code |
| X-06 | `server.fs.deny` includes sensitive patterns | Keep defaults: `['.env', '.env.*', '*.{crt,pem}', '**/.git/**']` | Removing deny rules exposes secrets and certificates |

---

## Validation Summary Template

```
## Review Results — [Project Name] — [Date]

### Version: Vite [6.x / 7.x / 8.x]

| Area            | Checks | Pass | Fail | Blocked |
|-----------------|--------|------|------|---------|
| Configuration   | 8      |      |      |         |
| Plugins         | 11     |      |      |         |
| HMR             | 6      |      |      |         |
| Env Variables   | 5      |      |      |         |
| Build           | 8      |      |      |         |
| SSR             | 6      |      |      |         |
| Security        | 6      |      |      |         |
| **TOTAL**       | **50** |      |      |         |

### Critical Failures (blocks deployment):
- [list any Security or Configuration FAILs]

### Non-Critical Failures (fix before merge):
- [list other FAILs]

### Notes:
- [version-specific observations]
```

---

## Reference Links

- [references/checklist.md](references/checklist.md) -- Complete validation checklist with detailed pass/fail criteria
- [references/examples.md](references/examples.md) -- Good code vs bad code examples for every check area
- [references/anti-patterns.md](references/anti-patterns.md) -- Consolidated anti-patterns from all Vite areas

### Official Sources

- https://vite.dev/config/
- https://vite.dev/guide/api-plugin
- https://vite.dev/guide/api-hmr
- https://vite.dev/guide/env-and-mode
- https://vite.dev/guide/ssr
- https://vite.dev/guide/build

Files in this skill

  • SKILL.md11.7 KB
  • references/anti-patterns.md13.9 KB
  • references/checklist.md15.8 KB
  • references/examples.md12.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.