[RFC] Modernize @payloadcms/ui: Tailwind CSS, Base UI Primitives, and a Mantine-inspired Styles API
#15543
Replies: 5 comments 5 replies
-
|
Baseui would be great. |
Beta Was this translation helpful? Give feedback.
-
|
I approach many organization with payload , and the one thing that usually stops them is the branding , |
Beta Was this translation helpful? Give feedback.
-
|
I don't agree with tailwind css! |
Beta Was this translation helpful? Give feedback.
-
|
For the last year I have joked multiple times that, if I had all the money in the world, I would offer Vitaly (creator of Mantine) a blank check to adapt, or build a new version of Mantine, specially for making the entire payload admin and all of it's components themed and completely reusable. If I could only give one suggestion to Payload for the rest of my life, it would be to consider Mantine, or something custom inspired by it for Payload v4. |
Beta Was this translation helpful? Give feedback.
-
|
I totally agree with the idea of making the Payload UI a bit more visually customizable by default. But overall, I have to say that working with Payload Admin is by far the best experience I've had with a CMS, and I've worked with dozens of them. So +1 from our team. We’re not just watching, we’re happy to contribute and help with the work. We've built a few custom UI libraries so far. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Some context first
I genuinely love Payload. It's become my go-to CMS, and I've been actively developing and publishing plugins for it. Every time I build something new, I'm reminded of how well-thought-out the core architecture is.
That said, there's one area where the developer experience breaks down significantly: making custom components visually indistinguishable from Payload's native admin UI. After building several plugins, I've run into the same walls repeatedly, and I believe a set of coordinated changes to
@payloadcms/uiwould solve these problems not just for me, but for the entire plugin ecosystem.This RFC is intentionally ambitious. I know it touches a lot of surface area, but I think the pieces fit together as a coherent vision. I'm also offering my time and effort to help implement this — more on that at the end.
The problem
1. Many internal components aren't exported as decoupled primitives
Many of the components used inside the admin panel (Input, Select, Tabs, DropdownMenu, etc.) are tightly coupled to internal wiring and either aren't exported or aren't usable in isolation. Plugin developers end up in one of two situations:
Related discussions: #9794, #4820, #293
2. The SCSS + BEM + CSS variables approach creates friction
The current styling system (SCSS with BEM naming, CSS layers, and
--theme-*custom properties) works well internally, but it creates a steep learning curve for anyone building on top of Payload:--theme-elevation-500,--base, etc.)Related discussion: #5028
3. No component documentation
As noted in the roadmap discussion (#293), the component library is marked "Done. Only missing docs." In practice, the lack of documentation makes
@payloadcms/uivery difficult to use without cloning the repo and reading source code. Community members have resorted to writing their own unofficial glossaries.Proposed solution
I'm proposing four coordinated changes that work together as a system:
1. Replace
src/elementsprimitives with Base UIBase UI reached v1.0 in February 2026 with 35 headless components. It's built by the creators of Radix UI and covers exactly the primitives Payload currently maintains in-house: Select, Tabs, Menu, Dialog, Combobox, Switch, Checkbox, Input, Field, and more.
Why Base UI specifically:
data-*attributes for state — components exposedata-disabled,data-selected,data-open, etc., which are perfect for Tailwind's attribute selectorsThis would let Payload's team stop maintaining low-level interaction logic (keyboard handling, focus traps, ARIA attributes, portal management) and focus on the CMS-specific composition layer on top.
Before (current internal primitive):
After (Base UI primitive, styled by Payload):
2. Switch entirely to Tailwind CSS
Drop the SCSS + BEM + CSS variables approach and adopt Tailwind CSS as the sole styling system for the admin panel.
Why this makes sense now:
tailwind.configfor the frontend. Having the admin panel speak the same language removes a major integration pain point.@themeblocks in CSS, which maps cleanly to a theming system that app developers can override without touching JavaScript configs.@layer payload-default. Tailwind v4 also uses CSS layers natively. The mental model aligns.dark:variant with a class-based toggle replaces the current approach of mirrored CSS variables. The theme's CSS custom properties can be swapped under a.darkselector, and Tailwind picks them up automatically — no need to maintain two parallel sets of variables.3. Mantine-inspired
classNamesprop for inner element customizationThis is the replacement for BEM targeting. Instead of relying on CSS class name conventions that can break between versions, every
@payloadcms/uicomponent would expose a typedclassNamesprop that maps named inner elements to CSS classes.How it works:
Every component defines its internal structure as a set of named selectors (root, label, input, error, description, icon, etc.). The consumer passes an object mapping those selectors to class strings.
Why this beats BEM:
4. App-level Tailwind config overrides for theming
As a nice side-effect of switching to Tailwind, theming the admin panel becomes straightforward for app developers. Payload would define its design tokens as CSS custom properties, and the app developer overrides them in the existing
src/app/(payload)/custom.scss:This isn't a plugin developer concern — it's simply a cleaner theming story for anyone deploying a Payload app who wants the admin panel to match their brand.
Documentation: Storybook + AI-ready markdown
Storybook with autodocs
Every component in
@payloadcms/uishould ship with a Storybook story. Using Storybook's autodocs feature, JSDoc comments on component props automatically generate interactive documentation:Developers see this rendered as an interactive playground with a controls panel — they can toggle props, see variants, and copy code. No separate documentation site to maintain.
Auto-generated markdown for AI agents
As a build step, JSDoc + Storybook metadata can be extracted into structured markdown files:
These files can live alongside the source and be consumed by AI coding agents (Copilot, Cursor, Claude, etc.) as context, making it dramatically easier to generate correct Payload admin components.
Migration path
I'm not suggesting this happens overnight. A realistic migration could look like:
@payloadcms/ui. No migration yet — just the tooling foundation to develop against.classNames, developed in Storybook. Ship them alongside existing ones. Plugins can start adopting them immediately. Nothing breaks.classNamesAPI becomes the official styling contract.Phases 1–2 are purely additive — existing components keep working unchanged. Breaking changes only land in phases 3–4, giving the ecosystem time to migrate.
I'd like to help
I'm not just filing a feature request. I actively develop Payload plugins and run into these problems on every project. I'm willing to contribute to the implementation.
If the team is open to this direction, I'd love to start a conversation about where to begin and how to coordinate.
Beta Was this translation helpful? Give feedback.
All reactions