MENU
CSS Configurations
1. cssChunking
cssChunking is an experimental feature in Next.js that controls how CSS is split, ordered, and loaded. It's designed to optimize performance by reducing the amount of CSS the browser has to download and parse for each route.
In large applications, CSS can grow significantly. By default, without chunking, all CSS may be bundled together. This results in large initial page loads, even if many styles aren't used on the first render.
Chunking reduces this overhead by splitting CSS based on usage and allowing route-level or component-level styles to be loaded only when needed, reducing render-blocking resources and improving load performance.
Instead of shipping a single large CSS file with styles for the entire application, CSS chunking enables per-route CSS delivery, allowing users to download only what's necessary.
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig = {
experimental: {
cssChunking: true, // true(default), false, or 'strict'
},
} satisfies NextConfig;
export default nextConfig
🔧 Available Options:
- true (default): Next.js analyzes import order and merges CSS files when possible. Aims for fewest requests, best for most apps.
- false: Disables CSS chunking. All styles are loaded as-is, in the order they're encountered. May lead to duplicate CSS loading across routes.
- 'strict': Enforces import order strictly. Prevents merging styles that were imported in different orders across modules. Use this if you encounter CSS order issues (e.g., broken styles due to dependencies between CSS files).
Use the 'strict' mode if:
- You import a.css and b.css in multiple files but in different orders.
- b.css depends on styles from a.css.
- In true mode, Next.js might merge them without maintaining order → breaking your styles.
With 'strict', the import order is preserved, ensuring CSS dependencies load correctly—at the cost of generating more chunks and requests.
This experimental feature works best with CSS Modules and CSS-in-JS patterns.
Chunking logic is based on module import graphs—if import paths are inconsistent, results may vary.
Some global styles (like third-party libraries) may not benefit from chunking.
2. inlineCss
The inlineCss configuration in Next.js is an experimental feature that enables inlining CSS directly in the <head> of your HTML document, rather than linking to external .css files.
inlineCss changes how CSS is delivered to the browser by replacing <link rel="stylesheet"> tags with <style> tags in the HTML head. This means CSS is directly embedded in the HTML, reducing the need for additional network requests.
//next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
inlineCss: true,
},
}
export default nextConfig;
With inlineCss enabled, all global and scoped CSS is included in <style> tags in the HTML head. No external stylesheets are loaded on initial load. When navigating between static pages, CSS will fall back to using <link> tags to avoid duplication.
Inlining CSS can dramatically improve performance in certain scenarios:
- ✅ First-Time Visitors: Eliminates CSS file download delays. Leads to faster First Contentful Paint (FCP) and Largest Contentful Paint (LCP).
- ✅ Slow Connections: Reduces network round trips. Useful for regions with high latency or slow internet speeds.
- ✅ Atomic CSS Libraries (like Tailwind CSS): Tailwind generates small, page-specific CSS. Inlining ensures minimal CSS per page and eliminates unused styles.
Inlining isn't always a good idea:
- ❌ Large CSS Bundles: Embedding large CSS directly in HTML can bloat the response size, slowing Time to First Byte (TTFB). Affects users on slow connections or low-end devices.
- ❌ Dynamic/Per-Page CSS: Leads to duplicated styles across pages. Increases page size unnecessarily for multi-page apps.
- ❌ Cache Inefficiency: Browsers can't cache inline styles. Returning users will always download styles again, even if unchanged.
💡 Global Only: You cannot inline CSS on a per-page basis—it's either all inline or all external.
🌀 Duplication: On the first page load: CSS appears inline in the <style> tag. It is also included in the React Server Component (RSC) payload.
🔄 Navigation Behavior: When navigating between statically generated pages, Next.js falls back to external CSS to avoid duplicating styles in each HTML page.
⚙️ Production Only: This feature is disabled in development mode. It only works in production builds.
💡 Best Practices:
- Use with Tailwind CSS or minimal CSS setups.
- Combine with Critical CSS extraction for hybrid strategies.
- Avoid enabling in large or legacy projects with monolithic CSS.
3. sassOptions
The sassOptions configuration in Next.js allows you to customize how the Sass compiler is used in your application. This is useful when you want more control over how styles are processed, such as injecting global variables, customizing import paths, or specifying which Sass implementation to use.
You can:
- Add global Sass variables/mixins
- Use a specific Sass implementation (e.g., sass-embedded)
- Set include paths
- Customize output styles, indentation, etc.
// next.config.ts
// additionalData injects the given Sass code (e.g., defining $var: red) into every .scss or .sass file automatically.
// implementation: 'sass-embedded' tells Next.js to use the Embedded Sass compiler, which can offer performance improvements or different behaviors from the default.
import type { NextConfig } from 'next'
const sassOptions = {
additionalData: `
$var: red;
`,
}
const nextConfig: NextConfig = {
sassOptions: {
...sassOptions,
implementation: 'sass-embedded',
},
}
export default nextConfig;
Although only implementation is typed in Next.js, you can still use any valid Sass options, including:
- additionalData - Prepends Sass/SCSS code to every file (e.g., shared variables or mixins).
- includePaths - Lets you import from custom folders without using relative paths.
- indentType - Choose between "space" or "tab" for indentation.
- indentWidth - Number of spaces/tabs per indentation level.
- outputStyle - Controls formatting of compiled CSS (compressed, expanded).
- implementation - Custom Sass implementation (e.g., sass, sass-embedded).
//This automatically includes styles/globals.scss in all stylesheets.
sassOptions: {
additionalData: `@import "styles/globals";`
}
//Now you can do @import "buttons"; instead of @import "../../styles/buttons";.
sassOptions: {
includePaths: ['styles', 'components']
}
✅ Good to Know: Only the implementation key is typed in Next.js. Others work, but are not autocompleted or type-checked.
⚠️ Path Issues: Be careful with includePaths—it may require absolute paths (path.join(__dirname, 'styles')) depending on your project structure.
🧪 Embedded Sass: The sass-embedded implementation is still evolving; check for compatibility or bugs with specific syntax/features.
4. useLightningcss
The useLightningcss configuration option in Next.js enables experimental support for using Lightning CSS — a high-performance CSS parser, transformer, and minifier written in Rust. This option is part of the experimental configuration namespace and is not yet recommended for production environments due to its evolving nature.
Lightning CSS is a CSS toolchain developed by the creators of Parcel, designed to be:
- Extremely fast (thanks to Rust)
- Modern (supports latest CSS syntax and features)
- Compact (minifies with advanced optimizations)
- Smart (handles vendor prefixing, nesting, logical properties, etc.)
When you enable useLightningcss, you're instructing Next.js to replace its default PostCSS-based pipeline with Lightning CSS for CSS transformations.
//next.config.ts
//This minimal config tells Next.js to process and minify CSS using Lightning CSS during the build.
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
useLightningcss: true,
},
}
export default nextConfig;
🔧 Features of Lightning CSS
- CSS Minification: Lightning CSS aggressively optimizes and reduces the size of your stylesheets.
- Vendor Prefixing: Automatically adds prefixes for cross-browser support based on target browsers.
- CSS Nesting: Supports native CSS nesting without relying on preprocessors like Sass.
- Logical Properties: Can transform logical properties for better cross-browser compatibility.
- Modern Syntax Support: Handles newer CSS features such as @layer, @scope, custom media queries, and more.
⚠️ This feature is still being tested. APIs and behavior might change in future releases. Some PostCSS plugins or custom PostCSS config (e.g., Tailwind with plugins) may not work with Lightning CSS. There is no fine-grained control or plugin system like PostCSS yet. In some versions, Lightning CSS may not be used during next dev, only during production builds.
💡You might want to try enabling useLightningcss if:
- You're building a performance-sensitive app (e.g., mobile-first or static sites).
- You're not using PostCSS plugins that conflict with Lightning CSS.
- You're curious about cutting-edge web tooling and want to help test new features.
❌ Avoid enabling useLightningcss if:
- Your build relies on custom PostCSS plugins, such as Tailwind CSS with custom configuration.
- You're deploying a mission-critical production app — stick with stable defaults instead.