{"dataset":{"id":"00000000-0000-0000-0000-000000000034","slug":"vite-best-practices","name":"Vite best practices","description":"Source-linked guidance on Vite fundamentals: the dev server and HMR, static assets, production builds, env variables and modes, and performance. Scoped to Vite; not a general bundler corpus.","visibility":"public","version":1,"documentCount":5,"publisher":"Koskamo editorial","license":"Original summaries; linked sources retain their own terms.","reviewedAt":"2026-10-04T00:00:00.000Z","readOnly":true,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},"total":5,"documents":[{"title":"Performance tuning and dependency pre-bundling","sourceUrl":"https://vite.dev/guide/performance.html","text":"The dev server hard-caches pre-bundled dependencies and answers source requests with fast 304 responses, so keep browser caching on — disabling it in DevTools noticeably slows startup and full-page reloads, and a dev-only browser profile without extensions avoids interference. Audit community plugins, whose performance is out of Vite's control: buildStart, config, and configResolved hooks are awaited during startup so they must not run long operations, large conditional dependencies should be dynamically imported, and resolveId, load, and transform hooks should bail early on a keyword or extension check before full transformation. Measure with vite --debug plugin-transform, vite --profile plus speedscope, or vite-plugin-inspect. Prefer explicit import paths over resolve.extensions guessing — the default seven-extension list can cost six filesystem checks per import — and with TypeScript enable \"moduleResolution\": \"bundler\" and \"allowImportingTsExtensions\": true. Avoid barrel files, which force fetching and transforming every re-exported module for a single API; import the file directly instead. Warm up known-hot files with server.warmup.clientFiles, prefer plain CSS over preprocessors, and import SVGs as strings or URLs rather than transforming them into components. Run this audit before reaching for heavier tooling — Koskamo editorial guidance. Scope: Vite. Reviewed October 4, 2026.","id":"vite-best-practices:Performance tuning and dependency pre-bundling","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Environment variables and modes","sourceUrl":"https://vite.dev/guide/env-and-mode.html","text":"Vite exposes constants under the import.meta.env object, defined as globals during dev and statically replaced at build time so tree-shaking stays effective — code inside if (import.meta.env.DEV) is dropped from production builds. Built-in constants are MODE, BASE_URL (from the base config option), PROD, DEV (always the opposite of PROD), and SSR. Custom env variables appear as strings under import.meta.env, and only variables prefixed with VITE_ reach client-side source code, so avoid that prefix for anything sensitive: VITE_* values are bundled into the source at build time, and secrets belong behind a backend server or serverless functions. Parsed values are always strings even when they look numeric or boolean, so convert types yourself. Vite uses dotenv to load .env, .env.local (ignored by git), .env.[mode], and .env.[mode].local; mode-specific files take priority over generic ones, variables that already exist when Vite executes have the highest priority and are never overwritten, and dotenv-expand expands variables out of the box. Files load at startup, so restart the server after changes, and add *.local to .gitignore. Scope: Vite. Reviewed October 4, 2026.","id":"vite-best-practices:Environment variables and modes","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Building for production","sourceUrl":"https://vite.dev/guide/build.html","text":"Run vite build to deploy for production: by default it uses <root>/index.html as the build entry point and produces a bundle suitable for a static hosting service. The production bundle targets browsers compatible with Baseline Widely Available as of a date fixed per major release — Chrome >=111, Edge >=111, Firefox >=114, and Safari >=16.4 for the current major — customizable via the build.target option down to es2015, though Vite still requires browsers with native ESM dynamic import and import.meta. Vite handles syntax transforms only and does not cover polyfills; support legacy browsers with @vitejs/plugin-legacy, which generates legacy chunks and polyfills that load conditionally only in browsers without native ESM. Deploying under a nested public path needs only the base option or vite build --base=/my/public/path/; set \"base\": \"./\" when the base path is not known in advance. When a dynamic import fails, Vite emits a vite:preloadError event whose payload holds the original error and whose default can be prevented — useful after redeploys delete old assets, provided the HTML is served with Cache-Control: no-cache. vite build --watch rebuilds on file changes. Scope: Vite. Reviewed October 4, 2026.","id":"vite-best-practices:Building for production","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Static asset handling and import queries","sourceUrl":"https://vite.dev/guide/assets.html","text":"Importing a static asset returns its resolved public URL: imgUrl is /src/img.png during development and becomes a hashed name such as /assets/img.2d8efhg.png in the production build. Imports may use absolute public paths (based on the project root in dev) or relative paths, CSS url() references are handled the same way, and the Vue plugin converts asset references in SFC templates into imports automatically. Common image, media, and font filetypes are detected as assets automatically; extend the internal list with the assetsInclude option. Referenced assets join the build assets graph, get hashed file names, can be processed by plugins for optimization, and are inlined as base64 data URLs when smaller in bytes than the assetsInlineLimit option — Git LFS placeholders are excluded from inlining. TypeScript does not recognize asset imports as valid modules by default; include vite/client to fix that. Use query suffixes for explicit control: ?url forces a URL import, ?inline and ?no-inline control base64 inlining, ?raw imports the asset as a string, and ?worker or ?sharedworker imports a script as a web worker emitted as a separate chunk (?worker&inline inlines it as base64). Scope: Vite. Reviewed October 4, 2026.","id":"vite-best-practices:Static asset handling and import queries","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Dev server and instant HMR over native ESM","sourceUrl":"https://vite.dev/guide/why.html","text":"Vite was created to fix painfully slow dev server startups, sluggish hot updates, and long build times by rethinking how code is served during development. Instead of bundling the entire application upfront, it splits the work in two: dependencies that rarely change are pre-bundled once using fast native tooling so they are ready instantly, while application source code is served on-demand over native ES modules — the browser loads only what the current page needs and Vite transforms each file as it is requested. Dev server startup is therefore nearly instant regardless of application size, and editing a file triggers Hot Module Replacement (HMR) over native ESM that updates just that module in the browser, with no full page reload or rebuild wait. Unbundled ESM still ships poorly in production because nested imports add network round trips, so optimized production builds remain bundled. Vite's plugin API follows Rollup's conventions, and the toolchain is now unified on Rolldown, a Rust bundler that uses Oxc for parsing, transforming, and minifying. Scope: Vite. Reviewed October 4, 2026.","id":"vite-best-practices:Dev server and instant HMR over native ESM","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"}]}