Next.js inlineCss: what it does, when to try it, when to skip it
- Next.js
- Performance
- CSS
An experimental next.config flag puts your CSS in a style tag in the head instead of separate link requests—good for first paint on slow networks and small atomic CSS, less ideal for repeat visitors and huge style bundles. Here is the trade-off in plain language.
Two ways to ship CSS
Next.js can ship your styles in two broad ways: the usual route uses link tags so the browser downloads CSS files after it sees the HTML, or you can turn on an experimental option called inlineCss. When inlineCss is true, Next inlines generated CSS as style blocks in the document head instead of emitting those extra link-based requests for styles. The idea is simple: fewer round trips on the first load so the browser can paint sooner.
You enable it in next.config.ts (or next.config.js) under experimental:
experimental: {
inlineCss: true,
}
Treat it as a lab feature—the docs say it may change, is not recommended for production yet, and they want feedback on GitHub. That is your cue to experiment on previews or side projects, not to flip it on silently for every user without measuring.
Why would you try it? The classic problem is the request waterfall. The browser downloads HTML, parses it, discovers link tags for CSS, then fetches those files before it can fully apply styles and render. Inlining puts the critical styles with the first HTML response, so you skip that extra hop for stylesheet discovery and download on the first visit. That often helps First Contentful Paint and Largest Contentful Paint when CSS was a real part of the delay.
The win is strongest for first-time visitors. CSS files are render-blocking; inlining removes the initial delay of fetching them the first time. People who already have your CSS cached in a separate file do not get the same benefit from inlining, because the old model was already cheap for them.
Slow or high-latency networks care a lot about each extra request. Cutting stylesheet round trips matters more when every hop hurts. Atomic utility CSS such as Tailwind also fits this story: you typically ship only the classes you use, so the generated CSS stays relatively small. Small inlined CSS gives you the network benefit without blowing up every HTML response the way a giant component-library stylesheet might.
When is the traditional link tag better? When inlined, styles are not cached separately from the document. Every full page load ships the CSS again with the HTML. Repeat visitors who would have reused a cached stylesheet lose that win. Large CSS bundles also argue for external files: a big blob in every HTML response raises Time to First Byte style pressure and denies the browser a dedicated cached style asset. Heavy frameworks like Bootstrap or Material UI are the kind of bundles the docs call out as a poor fit for inlining.
If many routes share the same stylesheet, one cached external file speeds up navigation across pages. Inlined CSS does not give you that cross-page cache benefit in the same way—each navigation story depends on how HTML and RSC payloads are delivered, but the mental model is: separate files can be long-lived cache entries; inlined CSS rides along with each page.
The documentation lists a few sharp edges worth remembering. Inlining is global in the config—you cannot turn it on for one route only. During the initial load, styles may appear twice in the pipeline: once inside style tags for server rendering and once inside the React Server Components payload, which is duplication you should be aware of when you debug size. When navigating to prerendered pages, Next may use link tags instead of inline CSS to avoid duplication. The feature does not run in development; you only see behavior in production builds, so compare prod builds when you measure.
Practical takeaway: if you use Tailwind or similar compact atomic CSS and your audience skews toward cold first loads or slow networks, inlineCss is worth a measured experiment. If your audience is mostly logged-in repeat visitors, or your CSS is large and shared, sticking with external stylesheets is often the friendlier default. For the exact API and updates, use the official page: https://nextjs.org/docs/app/api-reference/config/next-config-js/inlineCss.