PrimLagicPrimLagic

Moving from the Tailwind CDN to built CSS: why and how

By Ali Abdollahi · · 2 min read

For a quick start, Tailwind can load from the CDN with a single <script> tag. Tailwind itself says this is for development and experiments, not production. Why? Because the entire processing — finding used classes and building the CSS — happens in the visitor's browser: a big script must download, run, and only then does the page get styled. The result: worse LCP, dependence on an external service, and a harder content-security policy. I hit all of these on this very site and migrated every page.

The idea

Instead of building CSS in the browser, build it once at deploy time. The Tailwind CLI reads your files, keeps only the classes actually used, and emits one small CSS file. The browser downloads just that.

Steps

1. Install:

npm install -D tailwindcss@3

2. A tailwind.config.js with the paths that contain classes:

module.exports = {
  content: ["./**/*.html"],
  theme: { extend: { /* your previous inline config */ } },
};

3. An input file:

@tailwind base;
@tailwind components;
@tailwind utilities;

4. Build the minified output:

npx tailwindcss -i input.css -o assets/css/site.css --minify

5. In the HTML, remove the CDN script and add:

<link rel="stylesheet" href="/assets/css/site.css">

6. If your CSP allowed cdn.tailwindcss.com, remove it so the policy gets stricter.

Things to watch for

  • Classes built in JavaScript. Tailwind only finds complete class strings in files. 'bg-' + color + '-500' is not recognized; write the full class name. (The project cards on this site are rendered by JS, but since the template string contained complete class names, they were found.)
  • Per-page inline configs. If each page carried its own tailwind.config inside the HTML and the configs differ (a color or shadow with the same name but different value), one shared CSS file breaks things. My solution: one CSS file per page, built with that page's config.
  • Compare before and after. Screenshot the pages and diff them visually.

Result

On this site, each page's CSS landed between roughly 7 and 21 KB, the CDN and in-browser script dependency disappeared, and pages style correctly even without internet access — which makes local testing far easier.

TailwindCSSPerformance