.claude/skills/vite/vite-core/vite-core-environment-api/SKILL.md
Use when configuring SSR environments, edge workers, custom environments, or migrating to the Vite 6+ environment model. Prevents using the Environment API on Vite 5 (where it does not exist) and misconfiguring per-environment vs shared plugin scoping. Covers per-environment build and dev settings, EnvironmentOptions interface, custom environment providers, shared vs per-environment plugins, configuration inheritance, and migration from Vite 5 implicit environments. Keywords: vite, environment api, vite 6, SSR, edge workers, per-environment config, providers.
npx skillsauth add OpenAEC-Foundation/OpenAEC-Workspace-Composer vite-core-environment-apiInstall 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.
Vite 6+ ONLY — The Environment API does NOT exist in Vite 5 or earlier. ALWAYS verify you are targeting Vite 6.x before using any API described in this skill.
The Environment API formalizes how Vite handles different execution contexts. Before Vite 6, only implicit client and optional ssr environments existed. Vite 6 introduces explicit, named environments to match production setups (browser, Node server, edge workers, custom runtimes).
Core problem solved: Closing the gap between dev and build — server code now runs in matching runtimes during development.
| Scenario | Action Required |
|----------|----------------|
| SPA / MPA (no SSR) | None — Vite applies options to implicit client environment |
| SSR with default Node server | Minimal — existing ssr config maps to environments.ssr |
| Multi-environment (edge, workers) | New config — define named environments explicitly |
| Plugin authors | Migrate — move toward explicit per-environment hooks |
| Audience | Interaction Level |
|----------|------------------|
| End Users | Basic config for SPAs; explicit environments block for SSR/complex apps |
| Plugin Authors | Access per-environment hooks and consistent APIs |
| Framework Authors | Programmatic environment configuration and orchestration |
| Runtime Providers | Supply custom environment providers for their platforms (e.g., Cloudflare) |
The Environment API is in release candidate phase. Stability is maintained between major releases, but specific APIs remain experimental. The ecosystem should experiment before full stabilization in a future major version.
NEVER assume the Environment API works in Vite 5 — it is a Vite 6+ feature. Attempting to use environments config in Vite 5 will be silently ignored or cause errors.
NEVER expect optimizeDeps to propagate to server environments — it applies ONLY to client environments by default. ALWAYS configure optimizeDeps explicitly for non-client environments if needed.
NEVER mix Vite 5 SSR patterns (server.ssrLoadModule()) with Vite 6 Environment API — use the ModuleRunner API instead for Vite 6+.
ALWAYS test per-environment plugins in isolation — a plugin that works for client may fail silently in a server or edge environment.
ALWAYS verify that custom environment providers are compatible with your Vite 6.x minor version — the API is still stabilizing.
Top-level config options serve as defaults. Per-environment config in the environments block overrides them.
| Option Category | Inherits to All Environments? | Notes |
|----------------|-------------------------------|-------|
| resolve | YES | Per-environment override available |
| define | YES | Per-environment override available |
| build | YES | Per-environment override available |
| optimizeDeps | NO — client only | MUST be set explicitly for non-client environments |
| dev | YES | Per-environment override available |
| consumer | NO | Each environment declares its own consumer type |
UserConfig extends EnvironmentOptions {
environments: Record<string, EnvironmentOptions>
}
Top-level options in UserConfig ARE EnvironmentOptions for the default client environment. The environments record defines additional named environments that inherit from (and can override) these top-level defaults.
| Property | Type | Purpose |
|----------|------|---------|
| define | Record<string, any> | Global constant replacements for this environment |
| resolve | ResolveOptions | Module resolution (aliases, conditions, extensions) |
| optimizeDeps | DepOptimizationOptions | Dependency pre-bundling (client-only by default) |
| consumer | 'client' \| 'server' | Declares whether this environment targets a browser or server runtime |
| dev | DevEnvironmentOptions | Dev-server-specific settings for this environment |
| build | BuildEnvironmentOptions | Build-specific settings for this environment |
// vite.config.js — SPA (unchanged from Vite 5)
import { defineConfig } from 'vite'
export default defineConfig({
build: { sourcemap: false },
optimizeDeps: { include: ['lodash-es'] }
})
Vite internally applies all options to the implicit client environment. No environments block required.
// vite.config.js — SSR with edge worker
import { defineConfig } from 'vite'
export default defineConfig({
build: { sourcemap: false },
optimizeDeps: { include: ['lodash-es'] },
environments: {
server: {
consumer: 'server',
build: {
outDir: 'dist/server',
ssr: true
}
},
edge: {
consumer: 'server',
resolve: { noExternal: true },
build: {
outDir: 'dist/edge'
}
}
}
})
// vite.config.js — Cloudflare Workers environment
import { cloudflareEnvironment } from 'vite-plugin-cloudflare'
export default defineConfig({
environments: {
worker: cloudflareEnvironment({
build: { outDir: 'dist/worker' }
})
}
})
Runtime providers supply EnvironmentOptions objects that include provider-specific dev and build configuration. ALWAYS consult the provider's documentation for required options.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
// Shared plugins — applied to ALL environments
plugins: [react()],
environments: {
server: {
// Per-environment plugins — applied ONLY to this environment
plugins: [serverOnlyPlugin()]
}
}
})
ALWAYS place framework plugins (React, Vue) at the top-level plugins array so they apply to all environments. ONLY use per-environment plugins for environment-specific transforms.
Is your app a simple SPA or MPA (no SSR)?
├── YES → Do NOT configure environments. Use standard Vite config.
└── NO → Does your app have SSR?
├── YES → Does it target only Node.js?
│ ├── YES → Configure environments.server with consumer: 'server'
│ └── NO → Do you target edge/worker runtimes?
│ ├── YES → Add named environments (edge, worker, etc.)
│ │ Use custom providers if available
│ └── NO → Configure environments.server for your runtime
└── NO → Do you need per-environment build settings?
├── YES → Define named environments with specific build config
└── NO → Standard Vite config is sufficient
| Vite 5 Pattern | Vite 6 Equivalent |
|----------------|-------------------|
| server.ssrLoadModule() | ModuleRunner API |
| Implicit client + ssr environments | Explicit environments.client + environments.ssr |
| Plugin hooks handle all environments implicitly | Moving toward explicit per-environment plugin hooks |
| optimizeDeps.esbuildOptions | optimizeDeps.rolldownOptions (Rolldown replaces esbuild) |
| Top-level config applies to everything | Top-level config = client defaults; environments block for overrides |
vite package to ^6.0.0server.ssrLoadModule() — Migrate to ModuleRunner APIenvironments block — Explicitly define non-client environmentsconsumer property — Declare 'client' or 'server' for each environmentoptimizeDeps — If you had SSR-specific optimizeDeps, configure them per-environmentesbuildOptions — Use rolldownOptions for pre-bundling customizationdevelopment
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.