.claude/skills/vite/vite-agents/vite-agents-project-scaffolder/SKILL.md
Use when generating a new Vite project from scratch, adding Vite to an existing app, or scaffolding a production-ready Vite setup. Prevents missing vite-env.d.ts, incorrect plugin selection, and incomplete environment variable configuration. Covers vite.config.ts generation, TypeScript setup (tsconfig.json, vite-env.d.ts), package.json with scripts, index.html entry point, source directory structure, .env setup, and React/Vue/Svelte/vanilla support. Keywords: scaffold, project setup, vite.config.ts, tsconfig, React, Vue, Svelte, TypeScript, package.json, create-vite.
npx skillsauth add OpenAEC-Foundation/OpenAEC-Workspace-Composer vite-agents-project-scaffolderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
What framework?
├── React
│ ├── Need Babel plugins (relay, styled-components)? → @vitejs/plugin-react
│ └── No special Babel needs? → @vitejs/plugin-react-swc (ALWAYS prefer — 20x faster)
├── Vue
│ └── ALWAYS → @vitejs/plugin-vue
├── Svelte
│ └── ALWAYS → @sveltejs/vite-plugin-svelte
└── Vanilla TypeScript
└── No plugin needed
| Version | Transform Engine | Bundler | Config Key |
|---------|-----------------|---------|------------|
| Vite 6/7 | esbuild | Rollup | esbuild |
| Vite 8+ | Oxc | Rolldown | oxc |
ALWAYS check the installed Vite version before generating config. Vite 8 uses oxc and build.rolldownOptions; Vite 6/7 uses esbuild and build.rollupOptions.
| File | Purpose | Framework-Specific |
|------|---------|-------------------|
| vite.config.ts | Build tool configuration | Yes (plugin differs) |
| tsconfig.json | TypeScript compiler options | Yes (JSX settings) |
| tsconfig.node.json | Node-targeted TS config for vite.config.ts | No |
| src/vite-env.d.ts | Vite client type declarations | No |
| package.json | Dependencies and scripts | Yes (deps differ) |
| index.html | Application entry point | Yes (root element, script src) |
| src/main.tsx / src/main.ts | Application bootstrap | Yes (framework entry) |
| src/App.tsx / src/App.vue / src/App.svelte | Root component | Yes |
| .env.example | Environment variable template | No |
| .gitignore | Version control exclusions | No |
NEVER omit isolatedModules: true from tsconfig.json -- Vite uses transpile-only transforms that require this setting. Omitting it causes silent type-system mismatches.
NEVER set envPrefix to '' in vite.config.ts -- this exposes ALL environment variables (including secrets like DB_PASSWORD) to client-side code.
NEVER include type: "module" in package.json when using .ts config files -- Vite handles module resolution internally. Adding it causes resolution conflicts.
ALWAYS use /// <reference types="vite/client" /> in src/vite-env.d.ts -- this provides types for import.meta.env, asset imports, and CSS modules.
ALWAYS set "moduleResolution": "bundler" in tsconfig.json -- Vite resolves modules like a bundler, not like Node.js.
ALWAYS run type checking separately with tsc --noEmit -- Vite NEVER type-checks during dev or build.
| Framework | Plugin Package | Transform | When to Use |
|-----------|---------------|-----------|-------------|
| React | @vitejs/plugin-react | Babel | Need Babel plugins (relay, emotion, styled-components) |
| React | @vitejs/plugin-react-swc | SWC | Default choice -- 20x faster than Babel |
| Vue | @vitejs/plugin-vue | Vue compiler | ALWAYS for Vue SFC support |
| Vue + JSX | @vitejs/plugin-vue-jsx | Babel | Only when using JSX in Vue |
| Svelte | @sveltejs/vite-plugin-svelte | Svelte compiler | ALWAYS for Svelte |
| Vanilla | None | Built-in | No framework plugin needed |
React (SWC -- default choice):
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
export default defineConfig({
plugins: [react()],
})
React (Babel -- only when Babel plugins needed):
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
react({
babel: {
plugins: ['babel-plugin-styled-components'],
},
}),
],
})
Vue:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
})
Svelte:
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
export default defineConfig({
plugins: [svelte()],
})
Collect these before generating any files:
@ -> ./src (recommended)ALWAYS generate files in this order to avoid import resolution issues:
package.json (defines project identity and deps)tsconfig.json + tsconfig.node.json (TypeScript must resolve before config)vite.config.ts (depends on tsconfig for path resolution)index.html (entry point)src/vite-env.d.ts (type declarations)src/main.tsx or src/main.ts (application entry)src/App.tsx / src/App.vue / src/App.svelte (root component).env.example (environment template).gitignore (version control)After generating files, run:
npm install
NEVER run npm install before all files are generated -- package.json must be complete first.
ALWAYS include these settings (non-negotiable for Vite):
| Setting | Value | Reason |
|---------|-------|--------|
| isolatedModules | true | Vite uses transpile-only transforms |
| moduleResolution | "bundler" | Matches Vite's module resolution |
| target | "ES2020" or higher | Vite targets modern browsers |
| module | "ESNext" | Vite uses native ESM |
| types | ["vite/client"] | Provides import.meta.env types |
| skipLibCheck | true | Speeds up type checking |
Framework-specific JSX settings:
| Framework | jsx | jsxImportSource |
|-----------|-------|-------------------|
| React | "react-jsx" | "react" |
| Vue | Not needed | Not needed |
| Svelte | Not needed | Not needed |
| Vanilla | Not needed | Not needed |
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true
},
"include": ["vite.config.ts"]
}
ALWAYS create .env.example with documented variables:
# Application
VITE_APP_TITLE=My Vite App
VITE_APP_VERSION=1.0.0
# API
VITE_API_BASE_URL=http://localhost:3000/api
ALWAYS extend ImportMetaEnv in src/vite-env.d.ts to match .env.example:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_APP_TITLE: string
readonly VITE_APP_VERSION: string
readonly VITE_API_BASE_URL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
.env.local
.env.*.local
*.local
NEVER gitignore .env or .env.example -- these contain non-secret defaults and serve as documentation.
CSS preprocessors require ONLY a package install -- NEVER a Vite plugin:
| Preprocessor | Package to Install | File Extension |
|-------------|-------------------|----------------|
| Sass | sass-embedded (preferred) or sass | .scss / .sass |
| Less | less | .less |
| Stylus | stylus | .styl |
NEVER install vite-plugin-sass or similar -- Vite has built-in preprocessor support.
ALWAYS prefer sass-embedded over sass -- it runs Dart Sass in a separate process for better performance.
export default defineConfig({
oxc: {
jsx: {
runtime: 'automatic',
},
},
build: {
rolldownOptions: {
output: {
manualChunks: undefined,
},
},
},
})
export default defineConfig({
esbuild: {
jsx: 'automatic',
},
build: {
rollupOptions: {
output: {
manualChunks: undefined,
},
},
},
})
NEVER mix version-specific config keys -- using esbuild in Vite 8 triggers a deprecation warning and internal conversion.
development
Use when integrating Vite with a backend framework, rendering Vite assets from server-side templates, or setting up dev/production HTML serving. Prevents incorrect manifest.json traversal and missing CSS chunk resolution in production. Covers build.manifest configuration, .vite/manifest.json structure, ManifestChunk properties, dev mode HTML setup, production rendering, CSS/JS chunk resolution, and modulepreload polyfill. Keywords: backend integration, manifest.json, ManifestChunk, Django, Laravel, Rails, modulepreload.
development
Use when encountering dev server startup failures, HMR issues, proxy errors, CORS blocks, or module not found errors during development. Prevents misconfiguring server.hmr behind reverse proxies and forgetting appType: 'custom' in middleware mode. Covers HMR full-reload debugging, proxy configuration, CORS setup, HTTPS certificates, server.fs.strict violations, port conflicts, WebSocket failures, file watcher issues, and middleware mode. Keywords: dev server, HMR, proxy, CORS, HTTPS, WebSocket, port conflict, server.fs.strict, middleware mode, file watcher.
development
Use when encountering pre-bundling errors, dependency resolution failures, stale cache issues, or slow development server startup. Prevents excluding CJS dependencies from pre-bundling (which breaks runtime module resolution) and misconfiguring optimizeDeps. Covers CJS/ESM conversion failures, missing dependency auto-discovery, optimizeDeps configuration, monorepo linked dependencies, cache invalidation, browser cache staleness, and large dependency tree performance. Keywords: pre-bundling, optimizeDeps, CJS, ESM, cache, dependency resolution, monorepo, node_modules/.vite.
development
Use when encountering Vite build failures, chunk size warnings, or version-specific build errors. Prevents the common mistake of using deprecated rollupOptions in v8 or misconfiguring build targets and minifiers. Covers Rolldown/Rollup bundling failures, CSS minification errors, sourcemap problems, library mode build failures, BundleError handling, and asset processing errors. Keywords: build error, Rolldown, chunk size, sourcemap, library mode, minify, BundleError, rollupOptions, build.target.