Learn Tailwind CSS - Production Hardening & Best Practices
Episode 22 of 23

Learn Tailwind CSS - Production Hardening & Best Practices

This closing episode covers production hardening: a final checklist covering build-size, CSP, SRI, caching, and accessibility audits, avoiding runtime Tailwind injection in production, and documenting utility conventions, allowed custom classes, and component contracts for your team.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Congratulations, you've reached the final episode! Episode 22 wraps everything into one: production hardening. Here we put together a final checklist, make sure there's no Tailwind runtime in production, and document conventions so your team can continue what you built.

A healthy production isn't just "the app runs" — it means the smallest possible CSS, served with the right caching and security, accessible, and maintained by written conventions. All the layers we covered across 22 episodes culminate here.

Final Production Checklist

Run this checklist before every release:

Tailwind production checklist
1. Build-size dalam budget CSS
2. Content scanning sudah minimal dan tepat
3. CSS di-minify dan ber-hash filename
4. CSP style-src mengizinkan sumber yang dibutuhkan
5. SRI terpasang pada CSS dari CDN pihak ketiga
6. Cache-Control benar untuk file ber-hash
7. Audit aksesibilitas: fokus, kontras, reduced motion
8. RTL dan dark mode diuji

This order is deliberately arranged from the cheapest to the most time-consuming. CSS size can be checked in seconds in the terminal, while accessibility audits and RTL tests belong in the testing phase — that way the checklist can be run anytime without major friction.

Example commands for checking size and minification:

Final build with minify
npx tailwindcss -i src/styles.css -o dist/output.css --minify
du -h dist/output.css

--minify removes whitespace and comments; du -h dist/output.css shows the final size. Compare it against the budget threshold you agreed on in episode 20.

Build-time vs Runtime Injection

One decision is non-negotiable: no Tailwind runtime in production. The Play CDN and libraries that compile Tailwind in the browser are for development only. In production:

Signs of a correct production
Hanya file CSS statis yang di-deploy
Tidak ada script tailwind runtime di halaman
CSP style-src tidak membutuhkan 'unsafe-eval'

A Play CDN script like <script src="https://cdn.tailwindcss.com"></script> requires eval and dynamic inline styles — both at odds with a strict CSP. Build-time generation (episode 12) is the only safe and fast production path.

One more reminder: make sure there's no @tailwindcss/browser script or URL parameter that enables in-browser compilation. Any time runtime adds or changes classes after the page loads, the CSP and cache strategy built in episodes 12 and 13 become useless.

Warning

Inspect your production page in DevTools to make sure no script carries a Tailwind runtime. Look for tailwindcss in the script list or any initialization that compiles classes in the browser. Its presence is a sign of misconfiguration.

Documenting Conventions

A healthy production needs written rules, not just the senior engineer's memory. Create a conventions document covering:

Utility patterns — what's allowed and what's not:

Utility conventions
Boleh:
- Kombinasi utility inline pada komponen kecil
- variants md:, hover:, focus-visible:, dark:
- Arbitrary values untuk kasus sekali pakai
 
Hindari:
- Merangkai nama kelas dinamis
- Arbitrary values dari input pengguna
- Utility yang tidak dipakai (tinggalkan pattern)

Allowed custom classes: every custom class (e.g., .card, .btn) must be registered and have an owner — who maintains it and when it may change. This prevents "zombie CSS" that's defined but never used.

Component contracts: document your component APIs — available variants, the class slot for overrides, and state behavior. Use JSDoc or a markdown file:

JSComponent API documentation
/**
 * Button
 *
 * variants: primary | ghost | danger
 * sizes: sm | md | lg
 * slot: className (di-merge memakai tailwind-merge)
 * state: disabled, loading
 */
export function Button(props) { /* ... */ }

Written contracts make components used correctly and developed without breaking existing usage.

The best documentation is the one that gets read. Keep it near the code — for example as CONVENTIONS.md in the repo — and make it part of code review: every PR that adds a utility, variant, or new component must touch this document. Without that, conventions quickly go stale and turn back into truths scattered across team members' heads. Start from a short template: what's allowed, what's forbidden, and one real example for each rule.

No convention is perfect from day one; what matters is that it lives and gets revised together with the team whenever ambiguity surfaces.

Conclusion

Episode 22 closed the series with production hardening: a thorough release checklist, the firm decision for build-time generation, and documentation of conventions that lets your team continue safely. You now have a complete Tailwind CSS foundation from setup to production scale.

Key takeaways:

  • Run the build-size, CSP, SRI, caching, and a11y checklist before release.
  • Minify and hash filenames for safe caching.
  • No Tailwind runtime in production — always build-time generation.
  • A strict CSP rejects scripts that compile in the browser.
  • Document utility patterns, allowed custom classes, and component contracts.
  • Written conventions keep consistency as your team grows.

Thank you for following Learn Tailwind CSS from episode 0 through 22. Starting from pre-requisites, utility-first workflow, responsive design, dark mode, config architecture, plugins, design tokens, dynamic content security, delivery, CI/CD, performance, component API patterns, accessibility, framework integration, up to production hardening. Practice every episode in a real project, monitor your builds with the tools from episode 20, and grow with your team using the conventions from episode 22. Happy building fast, consistent, and secure UIs!