Tailwind CSS
v0 Framework Lock-in (React/Next.js Only)
7v0 strictly outputs React components and Next.js-compatible code only, forcing developers using Angular, Vue, Svelte, or other frameworks to perform extensive code conversion. The tool also mandates Tailwind CSS and doesn't generate TypeScript by default.
Conflicting styles when introducing Tailwind to existing projects
7Adding Tailwind to legacy projects with existing CSS can cause style conflicts and break existing functionality. Tailwind's style reset and generic class names (e.g., `.hidden`) can override existing CSS logic unintentionally.
Business model sustainability concerns due to AI-driven documentation replacement
7Tailwind's documentation traffic collapsed 40% between early 2023 and January 2026 as AI tools (ChatGPT, Claude, Cursor) replaced the need to visit docs. This disrupted the docs-to-premium-product conversion funnel, threatening the framework's long-term financial viability and development continuity.
Uncertainty about long-term framework viability and maintenance
7In early 2026, developers began worrying about Tailwind CSS's long-term sustainability due to revenue model collapse. Financial constraints limit the ability to fix problems, add features, and maintain four engineers, raising concerns about the framework's future.
Incompatibility with Web Components and Shadow DOM
7Tailwind CSS is completely unusable within the Shadow DOM, making it fundamentally incompatible with Web Components. While workarounds exist via build-process injection, they are acknowledged as hacks and not a native solution.
Vendor lock-in due to non-standard CSS syntax
7Tailwind's `@apply` directive only works within Tailwind and is not part of the CSS standard. CSS files written for Tailwind are fundamentally incompatible with other CSS frameworks and tooling, creating a one-way dependency that prevents migration.
Framework lock-in due to tight Tailwind coupling
6Projects become tightly coupled with Tailwind CSS, making it difficult or requiring significant refactoring to switch to another CSS framework or approach. This reduces long-term flexibility and portability.
Configuration file complexity and management
6As Tailwind projects grow, the tailwind.config.js file becomes increasingly complex and difficult to manage. Customizing themes, breakpoints, and integrating plugins requires careful consideration and can create large, hard-to-understand configuration files, especially problematic for larger teams managing intricate design systems.
PurgeCSS configuration gotchas and dynamic class generation failures
6Incorrect PurgeCSS setup causes unused class removal to break dynamically generated classes at runtime. Classes constructed via string interpolation (e.g., `object-position-[x y]`) fail to parse correctly, negating Tailwind's performance benefits.
Loss of fundamental CSS knowledge among developers
6Developers using Tailwind are abstracting away core CSS knowledge (Flexbox, Grid, positioning). Junior developers can use Tailwind classes but don't understand the underlying CSS properties, creating a generation gap in web platform fundamentals.
Stylesheet bloat if purging not configured correctly
5Tailwind's unused CSS purging requires proper configuration to avoid shipping excessive CSS. Without careful setup, projects can end up with unnecessary stylesheets that negate Tailwind's main performance advantage.
Misleading bundle size metrics and increased HTML payload
5While Tailwind markets tiny CSS bundles (<10kb), the actual HTML files grow 2-3x larger due to numerous utility classes per element. One project saw CSS shrink 45kb→8kb but HTML grow 120kb→340kb, resulting in a net 183kb increase, contrary to marketing claims.
Steep learning curve for utility-first approach
5Beginners struggle to understand the large number of utility classes, their naming conventions, and how they compose together. The onboarding time is significant even with comprehensive documentation, as developers must memorize extensive class names.
Custom CSS implementation in Tailwind projects negates framework benefits
5Complex projects require custom CSS alongside Tailwind utilities and @apply overrides, creating a hybrid CSS architecture. This defeats the purpose of using Tailwind and introduces maintenance complexity from multiple paradigms coexisting.
Additional build tool dependency and complexity
5Tailwind requires adding a build step to the development pipeline, preventing simple file-based deployment or client-side sandboxing without preprocessing. Integration with various build systems (e.g., SvelteKit) adds configuration complexity.
Debugging configuration and CSS specificity issues
5Debugging Tailwind configuration issues is less intuitive than debugging CSS itself. Developers must examine parent element styles, specificity conflicts, and conditional classes to understand unexpected style overrides, making troubleshooting complex and time-consuming.
Encourages semantic HTML anti-patterns with div soup
5Tailwind's utility-class approach promotes overuse of generic `<div>` and `<span>` tags instead of semantic HTML elements, leading to less accessible and maintainable markup that doesn't leverage modern custom elements.
Code duplication without component framework dependency
5Tailwind's philosophy discourages reusable classes, leading to repetition of identical utility class combinations across similar elements (buttons, links, headings, inputs). Avoiding duplication requires using component frameworks like React, Svelte, or Astro—not practical for simple static HTML projects like landing pages.
Complex debugging with multiple conflicting utility classes
5When styles break, developers must scan through many utility classes fighting for CSS specificity instead of viewing a single clear rule. Browser DevTools shows 47+ utility classes rather than straightforward CSS rules.
Utility classes always present, obstructing non-styling maintenance
5When maintaining HTML littered with Tailwind classes, even reading or updating content (not styles) becomes slow and cumbersome. The classes constantly interfere with workflow, requiring developers to work around styling details when they only need to modify markup content or add new elements.
Responsive design combinations become unwieldy
4Complex responsive design with multiple breakpoints creates deeply nested class combinations (e.g., `md:flex lg:block xl:grid`) that are hard to read, maintain, and reason about.
Design inconsistency without strict adherence to design systems
4The flexibility of Tailwind can lead to inconsistent designs across projects if developers aren't mindful about following design systems or reusing components. One Tailwind site can look completely different from another.
Frequent context switching between documentation and workflow
4Developers must constantly refer to Tailwind documentation to look up classes, causing workflow interruption. While IntelliSense and autocompletion help, the initial reliance on documentation is higher than with traditional CSS, leading to frequent context switching and reduced productivity.
Design consistency requires strict componentization discipline
4Maintaining consistent design without rigorous component creation is difficult. Developers can hand-pick slightly different utility classes for spacing and color, leading to unintended design variations across applications.
Poor syntax highlighting and lack of expressiveness in utility classes
4Tailwind class names receive no special syntax highlighting and are displayed as plain strings, reducing code expressiveness. CSS property names and values are more expressive and easier to scan. The short but non-descriptive nature of utility classes (compared to CSS keywords) compounds readability issues.
Additional runtime overhead from ecosystem dependencies
4Using Tailwind requires installing supplementary libraries (tailwind-merge, tailwind-aria, clsx, etc.) and VS Code plugins for usability. These add hidden runtime overhead and developer tool dependencies that aren't included in performance metrics.
AI-generated code produces unpredictable class stacking
4When using AI code generation tools with Tailwind, vague prompts result in unpredictable outputs, and AI frequently stacks too many utility classes together, creating excessive markup that requires manual cleanup.
Migration path uncertainty for teams seeking alternatives
4Teams evaluating alternatives to Tailwind (e.g., Material UI) face trade-off concerns. Alternative frameworks offer different benefits but introduce new compromises: bigger bundle sizes, steeper learning curves, more configuration, and less flexibility compared to Tailwind's constraints.
Lack of semantic meaning in utility class names
4Tailwind utility classes are functional but not semantic, making it harder to understand element purpose at a glance. Classes like `p-6, max-w-sm, rounded-xl` do not convey the meaning of elements. Developers accustomed to semantic classes like `.card, .card-header, .card-body` find utility-first approach less intuitive and harder to maintain.
Separation of concerns violated by mixing styles with markup
3Tailwind mixes CSS styling concerns directly into HTML markup, violating traditional separation of concerns principles and resulting in code that looks like inline styles, which many developers find aesthetically unpleasant.
Confusion between utility classes and design tokens creates redundancy
3Tailwind conflates utility classes with design tokens and binds them together unnecessarily, going against CSS principles and creating redundancy that could be achieved through CSS custom properties alone.
Unused CSS (zombie styles) remain in codebase despite purging
3Even though Tailwind purges unused utilities, nothing prevents developers from writing duplicate style properties in different classes or selectors, leaving unused styles in the codebase that get shipped to browsers with no effect.