This document describes how Vite processes CSS files during development and production builds, including transformation, module handling, preprocessor integration, and code splitting strategies.
For HTML-specific CSS injection, see 8.4 HTML Transformation For general asset handling, see 8.2 Asset Handling and Optimization
Vite's CSS processing system handles CSS files through a multi-stage pipeline that differs between development and production modes. In development, CSS is injected dynamically via JavaScript modules with HMR support. In production, CSS is extracted into separate files with optimization and code splitting applied.
The system supports:
Sources: packages/vite/src/node/plugins/css.ts114-165 packages/vite/src/node/plugins/css.ts227-234
CSS Processing Flow
CSS processing operates through two main plugins: cssPlugin (defined at packages/vite/src/node/plugins/css.ts295) and cssPostPlugin (defined at packages/vite/src/node/plugins/css.ts457). The cssPlugin handles transformation via compileCSS(), while cssPostPlugin handles dev injection and build extraction.
Sources: packages/vite/src/node/plugins/css.ts295-452 packages/vite/src/node/plugins/css.ts457-1088 packages/vite/src/node/plugins/css.ts1192-1580
CSS processing is configured via the css option defined in the CSSOptions interface:
| Option | Type | Default | Description |
|---|---|---|---|
transformer | 'postcss' | 'lightningcss' | 'postcss' | CSS transformer engine |
modules | CSSModulesOptions | false | undefined | CSS Modules configuration |
preprocessorOptions | object | {} | Options for scss, sass, less, styl, stylus |
preprocessorMaxWorkers | number | true | true | Run preprocessors in workers pool |
postcss | string | object | Auto-detected | PostCSS config path or options |
devSourcemap | boolean | false | Enable CSS sourcemaps in dev |
lightningcss | LightningCSSOptions | undefined | Lightning CSS options |
The default configurations are defined in cssConfigDefaults packages/vite/src/node/plugins/css.ts195-207
Sources: packages/vite/src/node/plugins/css.ts113-164 packages/vite/src/node/plugins/css.ts195-207
CSS Plugin Core Functions
The cssPlugin() function at packages/vite/src/node/plugins/css.ts295 creates the main CSS transformation plugin. It uses filter objects with CSS_LANGS_RE pattern to match CSS file requests.
Key Responsibilities:
?url, ?inline) packages/vite/src/node/plugins/css.ts337-363compileCSS() for transformation at packages/vite/src/node/plugins/css.ts1192cssModulesCache WeakMap at packages/vite/src/node/plugins/css.ts268preprocessorWorkerController in buildStart at packages/vite/src/node/plugins/css.ts324-330Load Hook Behavior:
{ id: CSS_LANGS_RE } at packages/vite/src/node/plugins/css.ts338-340urlRE.test(id) for ?url query at packages/vite/src/node/plugins/css.ts342isModuleCSSRequest(id) with ?url at packages/vite/src/node/plugins/css.ts343-348Transform Hook Behavior:
{ id: { include: CSS_LANGS_RE, exclude: [commonjsProxyRE, SPECIAL_QUERY_RE] } } at packages/vite/src/node/plugins/css.ts366-370urlResolver callback that calls idResolver(environment, url, importer) at packages/vite/src/node/plugins/css.ts374-421compileCSS() with environment and URL resolver at packages/vite/src/node/plugins/css.ts423-434moduleCache.set(id, modules) at packages/vite/src/node/plugins/css.ts435-437Sources: packages/vite/src/node/plugins/css.ts295-452 packages/vite/src/node/plugins/css.ts337-449
CSS Compilation Process
The compileCSS() function at packages/vite/src/node/plugins/css.ts1192 orchestrates the complete transformation pipeline.
Preprocessing Phase:
isPreprocessorRequest(id) at packages/vite/src/node/plugins/css.ts1222preprocessCSS() at packages/vite/src/node/plugins/css.ts2054 with worker pool if enabled.additionalData string or function at packages/vite/src/node/plugins/css.ts2089-2113Transformation Phase:
config.css.transformer === 'lightningcss' at packages/vite/src/node/plugins/css.ts1246doPostCSSTransform() at packages/vite/src/node/plugins/css.ts1636 loads config via resolvePostcssConfig().doLightningCSSTransform() at packages/vite/src/node/plugins/css.ts1818 uses bundleAsync().URL Resolution:
rewriteCssUrls(postcssResult.css, replacer) at packages/vite/src/node/plugins/css.ts1282-1395replacer function uses urlResolver(url, importer) callback at packages/vite/src/node/plugins/css.ts1286fileToUrl(this, resolved) to get Vite URL at packages/vite/src/node/plugins/asset.ts222Sources: packages/vite/src/node/plugins/css.ts1192-1580 packages/vite/src/node/plugins/css.ts1636-1816 packages/vite/src/node/plugins/asset.ts222
The cssPostPlugin() function at packages/vite/src/node/plugins/css.ts457 handles CSS output differently between development and build modes.
Development Mode Behavior:
isDirectCSSRequest(id) returns null at packages/vite/src/node/plugins/css.ts577-579inlineRE.test(id) exports string at packages/vite/src/node/plugins/css.ts580-582updateStyle helper for HMR support packages/vite/src/node/plugins/css.ts587-601Build Mode Behavior:
styles.set(id, css) at packages/vite/src/node/plugins/css.ts608dataToEsm(modules, ...) at packages/vite/src/node/plugins/css.ts556-559Sources: packages/vite/src/node/plugins/css.ts457-1088 packages/vite/src/node/plugins/css.ts520-632
CSS Modules are detected via cssModuleRE regex at packages/vite/src/node/plugins/css.ts227
Configuration Options (CSSModulesOptions interface at packages/vite/src/node/plugins/css.ts167-193):
scopeBehaviour: Scoping behavior ('global' or 'local').generateScopedName: Format or function for scoped names.localsConvention: Convention for exporting class names to JS.Implementation:
postcss-modules plugin at packages/vite/src/node/plugins/css.ts1734-1816dataToEsm(modules, ...) at packages/vite/src/node/plugins/css.ts556-559Sources: packages/vite/src/node/plugins/css.ts167-193 packages/vite/src/node/plugins/css.ts227 packages/vite/src/node/plugins/css.ts1734-1816
Vite supports Sass, Less, and Stylus preprocessors.
Worker Pool Processing:
When css.preprocessorMaxWorkers is enabled (default: true packages/vite/src/node/plugins/css.ts200), preprocessors run in worker threads using WorkerWithFallback packages/vite/src/node/plugins/css.ts25
Implementation Details:
preprocessCSS() at packages/vite/src/node/plugins/css.ts2054 dispatches to specific preprocessor logic.nodeResolveWithVite at packages/vite/src/node/plugins/css.ts2167Sources: packages/vite/src/node/plugins/css.ts2054-2591 packages/vite/src/node/plugins/css.ts25
PostCSS Processing
Uses postcss-load-config packages/vite/src/node/plugins/css.ts5 to resolve user configuration. Transformation is performed in doPostCSSTransform() packages/vite/src/node/plugins/css.ts1636
Lightning CSS (Experimental)
Lightning CSS is a high-performance transformer engine. Integration is handled in doLightningCSSTransform() packages/vite/src/node/plugins/css.ts1818 which handles bundling, minification, and CSS modules.
Sources: packages/vite/src/node/plugins/css.ts1636-1816 packages/vite/src/node/plugins/css.ts1818-2052
Vite supports CSS output strategies controlled by build.cssCodeSplit.
Pure CSS Chunk Optimization: Chunks containing only CSS (no JS exports) are tracked and optimized.
isPureCssChunk(chunk) packages/vite/src/node/plugins/css.ts1052getEmptyChunkReplacer() for format-specific cleanup packages/vite/src/node/plugins/css.ts1017-1075removedPureCssFilesCache packages/vite/src/node/plugins/importAnalysisBuild.ts15Sources: packages/vite/src/node/plugins/css.ts635-940 packages/vite/src/node/plugins/css.ts1017-1075 packages/vite/src/node/plugins/importAnalysisBuild.ts15
URL Resolution:
Vite resolves URLs in CSS files through rewriteCssUrls() packages/vite/src/node/plugins/css.ts1282
url() patterns via cssUrlRE packages/vite/src/node/plugins/css.ts1587-1594image-set() and -webkit-image-set().@import Inlining:
Vite inlines CSS @import statements during build to reduce requests.
hoistAtRules() at packages/vite/src/node/plugins/css.ts1582 to ensure correct CSS order.Sources: packages/vite/src/node/plugins/css.ts1282 packages/vite/src/node/plugins/css.ts1582-1634