Choosing Vite build.cssCodeSplit: Per-Chunk CSS vs Single Stylesheet
Decide whether Vite should emit one CSS file per JavaScript chunk or a single bundled stylesheet for production builds.
06 Apr 2026, 03:00 UTC

Problem and takeaway
After vite build, your application either loads one large stylesheet before rendering or loads many small CSS files that may arrive after their JavaScript. Vite's build.cssCodeSplit option controls this split. Choosing the wrong mode can slow initial render or force repeat downloads of unchanged styles.
Takeaway: keep the default per-chunk CSS for route-split single-page applications. Move to a single CSS file only for small multi-page sites, legacy browsers, or when measurements show one stylesheet improves cache hits enough to offset the larger first download. Validate in dist and vite preview, not in dev mode.
What build.cssCodeSplit controls
build.cssCodeSplit applies to Vite's Rollup-based production build. It does not change the development server or hot module replacement. The option works for single-page apps, multi-page apps, and library mode.
Code splitting means dividing build output into multiple files that load on demand. CSS extraction moves imported styles out of JavaScript into separate .css files. When splitting is enabled, Vite tries to match each CSS file to the JavaScript chunk that uses it.
Supported options compared
| Setting | Behavior | Best suited for | Main drawback |
|---|---|---|---|
cssCodeSplit: true (default) |
Emits one CSS file per JavaScript chunk; styles load alongside their chunk | Route-based single-page apps, large applications | More HTTP requests; possible flash of unstyled content if CSS arrives late |
cssCodeSplit: false |
Emits all CSS into a single stylesheet | Small multi-page apps, legacy browsers, simple cache strategy | Entire stylesheet re-downloads when any style changes; unused styles load on every entry |
Trade-offs
Per-chunk CSS helps initial render because a route only downloads the styles it needs. The downside is more HTTP requests, and if a CSS file arrives after its JavaScript, users may briefly see unstyled content, sometimes called a flash of unstyled content.
A single CSS file benefits from long-term browser caching across pages. However, changing one component style invalidates the whole stylesheet for every visitor. It also means every entry point downloads styles it may never use, increasing first-load parse time.
A practical way to compare is to build the same entry points twice, once with each setting, and compare total CSS bytes and request count in the browser Network tab.
Assumption
This guide assumes a current stable Vite release whose production build uses Rollup. Behavior in future Vite versions or non-Rollup build paths may differ.
Configure and validate
- Open
vite.config.tsin<project-root>. - Add or edit the
buildsection:
import { defineConfig } from 'vite'
export default defineConfig({
build: {
cssCodeSplit: false, // set true to restore default per-chunk behavior
},
})
- Run the build from
<project-root>:npx vite build. If yourpackage.jsondefines a build script,npm run buildis equivalent. Required permissions: read and write access to the project directory anddist/. Administrator privileges are not required. - Inspect the output. On macOS or Linux:
ls dist/assets/*.css. On Windows PowerShell:dir dist\assets\*.css. Count the files. - Start a local preview:
npx vite preview. Open browser DevTools, select Network, filter by CSS, and reload. Confirm the CSS request count matches the file count indist.
Expected results
true(default): multiple CSS files, each paired with a JavaScript chunk.false: one CSS file.
Risks
- Changing this setting invalidates prior build output caches.
- Do not judge behavior from the dev server;
build.cssCodeSplitgovernsvite buildoutput.
Limitations
- Per-chunk CSS relies on correct HTML link injection. Vite injects links automatically for standard
index.htmlentry points; custom entry points should be checked manually. - Older browsers without support for lazy stylesheet loading or
<link media>may need a single CSS bundle or additional polyfills. - Disabling code splitting means every page downloads unused styles, which can increase first-load parse time.
Rollback
Editing vite.config.ts and rebuilding changes dist/ state. To roll back, revert cssCodeSplit to its previous value or remove the line to restore the default, then run vite build again and redeploy the regenerated dist/ folder.
Practical check before deploy
Run a file count and compare it to your configured mode:
# macOS / Linux
find dist -name "*.css" | wc -l
If you set false and see more than one CSS file, verify that dynamic imports or multiple entry points are not forcing separate stylesheets. If you keep the default and see one file, confirm the option was not accidentally set to false.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.