Fifteen fronts · checked August 2026

Where the stack is grinding.

The open arguments in the ecosystem we build on — the foundations that moved, the forms that fail quietly, and the permission models that outgrew their role checks. Ranked by what each one costs a team that hits it, traced to first-party sources, and dated.

1 written up in full · 14 mapped and sourced. Every entry carries the date it was checked — nothing here updates itself.

Cost01 → 15
Structural · 5Recurring · 6Background · 4

Structural

Costs a migration, a re-platform, or a licence line — decided once, lived with for years.
01

The ground under Tailwind moved

Peak adoption, collapsed revenue, three of four engineers gone. What it means for everyone building on an open-source foundation.
What the research found
  • On 6 January 2026 Tailwind Labs laid off three of its four engineers, with revenue down close to 80% while the framework sat at roughly 75 million npm downloads a month.
  • Adam Wathan, in a GitHub comment: Tailwind is growing faster than it ever has and is bigger than it ever has been, and our revenue is down close to 80%.
  • The cause is not a competitor. AI assistants generate Tailwind without anyone visiting the docs, which is where the paid products were discovered.
  • Wathan declined a proposal to make the docs more AI-friendly, on the grounds it would accelerate the same collapse.
  • The argument that followed splits two ways: that venture-funded AI products monetise open source without paying maintainers, and that the sponsorship income made the layoffs avoidable.
  • The part that generalises past Tailwind: any project whose funding depends on people reading its documentation now carries the same exposure, and the ones that do not are the ones worth betting a stack on.
Sources

Checked 27 Aug 2026

02

Tailwind against the CSS that grew up

The v4 release is built on cascade layers, @property and color-mix — the same native CSS the framework is accused of papering over. And the upgrade renamed things quietly.
What the research found
  • Tailwind v4 is itself built on the modern CSS it is accused of papering over. Its own release notes name native cascade layers, registered custom properties via @property, and color-mix() as the foundation.
  • The default palette moved off RGB in v4: "We've upgraded the entire default color palette from rgb to oklch, taking advantage of the wider gamut."
  • The upgrade removed deprecated utilities outright rather than deprecating them — overflow-ellipsis becomes text-ellipsis, so the old class emits nothing instead of erroring.
  • The default shadow, radius and blur scales were renamed so every utility has a named value: shadow-sm became shadow-xs and shadow became shadow-sm, with the same shift on rounded, blur, drop-shadow and backdrop-blur. Existing markup keeps compiling, at the wrong visual weight.
  • JavaScript config files still work, but are no longer detected automatically — they must be loaded explicitly with @config — and corePlugins, safelist and separator are not supported in v4.
  • On adoption, State of CSS 2025: Tailwind drew 2,041 responses against Bootstrap's 1,194, from the 3,977 people who answered the frameworks question.
Sources

Checked 27 Aug 2026

03

MUI has not said where styling goes next

Pigment CSS announced, never shipped stable. v7 still on Emotion. An open issue asks the question the team has not answered.
What the research found
  • Issue #45759 asks the question directly and has no settled answer: in a world of React 19, RSC, shadcn and Tailwind, is Pigment CSS still the future of MUI?
  • Pigment CSS was announced, never shipped stable, and went back into refactoring for v1.
  • MUI v7 still ships on Emotion, and Base UI launched without a Pigment story.
  • The long-standing complaints sit underneath: 300kb+ gzipped at full library, roughly 12kb of Emotion runtime, and slower hydration under SSR.
  • In development, barrel imports from @mui/icons-material can be several times slower than path imports because of the sheer number of icons.
Sources

Checked 27 Aug 2026

04

One licence per developer

MUI X moved from ten seats to one licence per developer. The most concrete objection in every enterprise evaluation.
What the research found
  • MUI X moved from licensing the first ten developers to requiring a licence per developer — fifty developers now means fifty licences.
  • Existing customers were grandfathered and can keep renewing on the legacy plan.
  • The stated reason is keeping the price accessible for small teams, which does not address the teams the change actually hits.
  • Issue #10244 records the confusion it caused about whether the per-developer price was capped.
Sources

Checked 27 Aug 2026

05

Your headless base changed underneath you

Radix slowed after the WorkOS acquisition, Base UI shipped 1.0, and shadcn switched defaults. Whoever copied components owns the migration.
What the research found
  • Radix development slowed noticeably after the WorkOS acquisition, which put its long-term support in question.
  • Base UI shipped stable 1.0 on 11 December 2025 with 35 accessible components and a dedicated maintenance team.
  • Projects created with shadcn/create were already picking Base over Radix roughly two to one before the switch was official.
  • In July 2026 shadcn/ui made Base UI the default for new projects.
  • The uncomfortable part is not which library is better: whoever copied components into their own repo now owns a migration nobody will do for them.
Sources

Checked 27 Aug 2026

Recurring

Costs hours every sprint — paid continuously, and easy to stop noticing.
06

The form does not break, it goes quiet

Controlled against uncontrolled, validation that never fires, generics that silently drop type safety. The expensive class of bug.
What the research found
  • The recurring shape is not a crash. Things stop working without saying anything, which is the expensive class of bug.
  • MUI TextField under Controller produces the uncontrolled-to-controlled warning — a structural tension, since RHF is uncontrolled-first and MUI is controlled-first.
  • Validation silently does nothing when handleSubmit does not wrap the handler, or when a field was never registered.
  • Omitting the generic on useForm drops type safety across errors, watch and setValue, with no error to tell you.
  • watch across many fields degrades performance visibly on large forms.
Sources

Checked 27 Aug 2026

08

Who owns the form state now

React 19 actions cover a real slice of what a form library did. The unresolved part is what happens when the server has an opinion.
What the research found
  • react-hook-form was not built for React 19 actions or server-side form handling, and the discussion tracking it is still open.
  • The majority position is hybrid: RHF for client validation, React 19 and Next for the server side.
  • The bridge people actually use: feed useActionState's returned state into useForm as errors and default values.
  • The stronger position argues for dropping the dependency, because action-returns-state removes a whole category of sync bugs.
  • The live disagreement is server validation latency against the need for immediate client feedback.
Sources

Checked 27 Aug 2026

09

The debt inside schema-driven forms

You stop writing JSX and start debugging JSON. Runtime errors instead of compile-time ones, and cascading rules that stall the page.
What the research found
  • You stop debugging a component and start debugging a JSON document, which needs familiarity with the schema rather than the UI.
  • Schema validation happens at runtime, so errors arrive while running instead of while compiling.
  • Genuinely custom rendering still lives in JavaScript — the schema configures, it does not implement.
  • Under cascading rules the page stalls; distributed per-field state is what keeps linkage-heavy forms responsive.
  • Schemas with hundreds of fields become large documents that weigh on initial load.
Sources

Checked 27 Aug 2026

10

Who is allowed to restyle your component

Exposing className is called an anti-pattern by one side and a necessity by the other. Under Tailwind it becomes: whose class wins?
What the research found
  • One published position calls exposing className in React components an anti-pattern that produces brittle, unmaintainable code.
  • The opposite need is real: a design system without an escape hatch fails the first case it did not anticipate.
  • MUI opened an issue specifically to standardise sx across its libraries; StyleX opened the mirror-image discussion about supporting className.
  • Under Tailwind the same question turns operational — whose class wins when the consumer passes one? That is what tailwind-merge, cva and tailwind-variants exist to answer.
  • The underlying trade-off is flexibility through className, style and sx against a closed design language with controlled overrides.
Sources

Checked 27 Aug 2026

11

Permissions that outgrew their role checks

No clean way to express hierarchy, no standard way to deny one child while allowing the parent, and audit spread across a thousand ifs.
What the research found
  • Role checks scatter through the codebase, and string comparisons plus role lists stop scaling as features multiply.
  • There is no clean way to express hierarchy — dashboard granted but dashboard:checklist withheld.
  • There is no standard way to say deny this specific thing while allowing its parent.
  • Auditing is hard because decisions live in thousands of imperative ifs, duplicated across layers.
  • Non-developers cannot manage access without a code change.
  • The consistent warning: frontend checks are ergonomics, never security — they never replace the backend.
  • The direction of travel is permission-based rather than role-based; the UI does not need to know roles.
Sources

Checked 27 Aug 2026

Background

No direct cost — context that shapes how the two above get decided.
12

The case against your effect chain

The strongest case against effect chains is the one React itself publishes: rigid, fragile, and re-rendering between every step.
What the research found
  • React's own documentation makes the case: Effects are "an escape hatch from the React paradigm", and "Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone."
  • On chaining, the docs are explicit — the component and its children "have to re-render between each set call in the chain", and as requirements move "the 'chain' you wrote doesn't fit". The verdict: "Such code is often rigid and fragile."
  • An Effect that immediately updates state restarts the whole render-and-commit cycle from scratch.
  • The two cases the docs single out as never needing an Effect: transforming data for rendering, and handling user events.
  • The separate community complaint is over-abstracted custom hooks that own several responsibilities without declaring any, then get reused where they were never designed to go.
Sources

Checked 27 Aug 2026

13

Validation drifts, and nobody notices

The client validates enough for feedback, the server validates differently, and the requirement changes on only one side.
What the research found
  • This one is a practitioner pattern rather than a measured finding — treat it as a shape people recognise, not a statistic.
  • The reported failure is not writing validation twice, it is that the two copies diverge and nobody notices until production.
  • The client validates enough for fast feedback; the server revalidates, sometimes more strictly, sometimes differently.
  • A requirement changes and only one side is updated, because nothing links them.
  • The shared-schema answer is well understood; what it depends on is a boundary discipline that is easy to state and hard to hold.
Sources

Checked 27 Aug 2026

14

One colour, six repositories

The gap between what the designer changed and what the build renders — named tokens that do not survive the trip into code.
What the research found
  • A practitioner pattern rather than a measured finding — the shape is consistent across write-ups, the frequency is nobody's published number.
  • The example that recurs: a designer changes the primary colour, and the developer has to hunt that value across several repositories.
  • Designers use the newest variables assuming they match the codebase, while the value underneath is stale.
  • Tokens designed only from the design side produce long names and values that do not map cleanly onto CSS properties.
  • The convergent fix is a naming convention agreed before the system is built, not retrofitted after.
Sources

Checked 27 Aug 2026

15

Rebuilding the same admin panel again

Twenty entities turn a simple back office into a real application, and the low-code answer runs into its own pricing wall.
What the research found
  • Retool's pricing page lists Free, Team, Business and Enterprise. On deployment it says Retool "runs in the cloud or self-hosted in your own VPC" and that "Enterprise plans support both options" — it does not state that Team or Business include self-hosting.
  • Listed rates at the time of checking: Team €9 per builder and €5 per internal user, Business €46 per builder and €14 per internal user, Enterprise on request.
  • The engineering complaint underneath is older than any vendor: multiply one ordinary CRUD screen by ten or twenty entities and the simple back office is a real application.
  • That is the whole reason admin-panel frameworks exist — not to make CRUD interesting, but to stop rebuilding auth, tables and forms per entity.
Sources

Checked 27 Aug 2026