Proposal: mix phx.gen.csp — CSP Level 3 support for Phoenix

@steffend and @LostKobrakai I’d like to broaden the CSP discussion to something I think is related and worth reflecting on: a roadmap toward making Phoenix CSS-agnostic.

I’m not suggesting we rip out Tailwind or DaisyUI overnight — they serve their purpose well for quick starts. But I believe the project should gradually move toward being framework-agnostic on the CSS/component side. Here’s why:

The security argument

Once we implement CSP support in Phoenix (which this thread is about), the default template must be CSP-compatible out of the box. Today, DaisyUI has 2 components that require 'unsafe-inline' in style-src (daisyui#4475), and the initial response from their core contributors has been dismissive — a thumbs-down with no comment. We can’t guarantee that a third-party CSS library will align with Phoenix’s security goals.

The ecosystem has changed

When DaisyUI was adopted (March 2025), it was one of the few CSS-only component libraries that checked all the boxes José outlined in #6121. But the landscape has evolved rapidly:

  • Framework-agnostic component libraries are now abundant — Petal Components (1M+ Hex downloads), Mishka Chelekom (80+ components, generator-based), SaladUI (shadcn/ui-inspired), Noora, Doggo (headless/accessible), and more
  • Building UI is dramatically easier than before — AI tools, copy-paste component registries (shadcn model), and mature headless libraries mean developers no longer need a bundled CSS framework to be productive
  • Phoenix does server-side rendering — we send ready HTML to the client. Any CSS library that produces valid HTML+CSS works. We only ship the minimal JS each library needs for interactivity. This makes us naturally positioned to be CSS-agnostic

Evidence from the community

The data suggests the community is ready for this:

  • Forum thread on --no-daisy flag: 67 posts, 123 likes — the most engaged CSS discussion in the forum
  • Poll data: 35% of respondents want Tailwind without DaisyUI; 14% want neither
  • Issue #6626: José himself noted that DaisyUI creates a “cognitive lock-in” — AI agents only use DaisyUI when it’s available, even when plain Tailwind would be better. If this happens to AI, it likely happens to beginners too
  • Issue #6204: DaisyUI deprecated fieldset-label, breaking Phoenix’s CoreComponents — a maintenance cost we absorb from a dependency we don’t control
  • Issue #6433: The dark variant with system mode is still broken and open

What I’m proposing (not a revolution, an evolution)

A gradual roadmap, not a breaking change:

  1. Short term: Ensure the default template is CSP-compatible (the work in this thread). Document how to use Phoenix with different CSS libraries
  2. Medium term: Make CoreComponents a truly headless/semantic layer that any CSS library can style. Provide documentation and examples for popular libraries (DaisyUI, Petal, Mishka, plain Tailwind, etc.)
  3. Long term: Consider a pluggable CSS system in phx.new — similar to what @zachdaniel is exploring with Igniter, or the wizard-style installers he mentioned in #6121

DaisyUI can absolutely remain the default for quick starts. But the architecture should make it a choice, not a coupling. This aligns with Phoenix’s philosophy of being explicit and transparent — the same principles that make the framework great.

What do you think? Is this something worth exploring as part of the broader CSP effort, or should it be a separate discussion?

1 Like