This episode covers how to serve Tailwind CSS: build-time generation versus the Play CDN and their trade-offs, securing things with Content Security Policy and SRI when using a CDN, and caching strategies and HTTP headers for static files.

Tailwind CSS must reach the browser the right way. Episode 12 covers two delivery paths: build-time generation, which produces static files, and the Play CDN, which compiles in the browser. Both have major trade-offs, especially around security and performance.
Your delivery choice directly determines your application's security posture. Static CSS files can be locked down with Content Security Policy (CSP) and SRI; runtime scripts like the Play CDN are much harder to secure and aren't recommended for production. Let's break down both.
The standard approach: Tailwind runs at build time, producing a static CSS file deployed alongside your app:
npx tailwindcss -i src/styles.css -o dist/output.css --minifyThe result is a single small file that can be cached aggressively and fully secured with CSP. This is the only approach recommended for production.
The Play CDN compiles Tailwind in the browser when the page loads:
<script src="https://cdn.tailwindcss.com"></script>cdn.tailwindcss.com does runtime compilation — handy for prototyping, but not for production: it adds JavaScript weight, slows down first paint, can't be secured with a simple CSP, and doesn't use JIT tree-shaking as efficiently.
Warning
The Play CDN is explicitly meant for development only. Never rely on it in production — use build-time generation and deploy a minified static CSS file.
With static files, CSP can be quite strict. Only allow your own origin for styles:
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'Note: many libraries inject inline styles, so style-src often needs 'unsafe-inline'. A stricter approach uses a nonce or hash for inline style tags:
<link rel="stylesheet" href="/css/app.css" />
<style nonce="random-nonce-value">...</style>And the header:
Content-Security-Policy: style-src 'self' 'nonce-random-nonce-value'If your CSS file is pulled from a third-party CDN, add SRI so the browser verifies the file's integrity before using it:
<link
rel="stylesheet"
href="https://cdn.example.com/app.css"
integrity="sha384-X8K8t2Q1ZH9ROYN2Yd1MDAK7Qx0iKZQZ0s5AKX1z9QvXhAQ"
crossorigin="anonymous"
/>integrity="sha384-..." is a hash of the file's contents. If the file is modified on the CDN, the browser rejects it — protection against supply chain attacks.
CSS with a version-hashed name can be cached aggressively:
Cache-Control: public, max-age=31536000, immutableBecause the file name changes when the contents change, browsers can store it forever. For files without a hash (e.g., app.css), use a short cache plus validation:
Cache-Control: public, max-age=0, must-revalidate
ETag: "abc123def456"ETag lets the browser send If-None-Match and receive a 304 response when the file hasn't changed. The combination Cache-Control: public, max-age=31536000, immutable with a hashed filename is the standard best practice.
One detail that's often missed: set a Vary: Accept-Encoding header on CSS responses so the CDN doesn't mix gzip and brotli variants on the same URL. That keeps compression optimal without risking serving the wrong payload to a given client.
If static files are served through a service worker, treat CSS as part of an immutable precache — not a cache that can be updated anytime. The worker deciding when to fetch a new version must use the hashed file name as its key, not a fixed URL like /css/app.css.
Episode 12 prepared fast and secure CSS delivery: build-time generation as the production standard, Play CDN only for development, security with CSP and SRI, and caching strategies with the right HTTP headers.
Key takeaways:
style-src controls stylesheet sources and can be tightened with a nonce.immutable.max-age=0 plus ETag for revalidation.Next, in episode 13, we'll cover CI/CD and build pipelines — running Tailwind builds on CI with proper caching, setting up linting with eslint-plugin-tailwindcss, and deployment strategies to Vercel, Netlify, or static hosting.