Appearance
UI Framework Candidates
Soma and Tapia currently use React 19, Tailwind CSS v4, DaisyUI, Floating UI, Motion, and a shared @soma/ui package. That works, but DaisyUI is carrying too much visual opinion into an app that wants a dense, native-feeling desktop surface.
What We Need
- Headless or lightly styled primitives so
@soma/uiremains the design-system boundary. - Strong accessibility defaults for menus, dialogs, comboboxes, tabs, toolbars, trees, and keyboard navigation.
- Tailwind-compatible styling with no mandatory CSS-in-JS runtime.
- React 19 compatibility and good behavior inside Electron/Chromium.
- Composable APIs that can support Soma's workspace shell and Tapia's focused interaction states without fighting Motion.
Leading Candidate: Base UI
Base UI is the best first candidate to prototype. It is an unstyled React component library focused on accessibility, performance, and developer experience, and its docs explicitly support Tailwind, CSS modules, plain CSS, and CSS-in-JS.
Why it fits Soma:
- It lets us keep Tailwind v4 and
@soma/uias the visible design layer. - It avoids DaisyUI's global class vocabulary and theme assumptions.
- It gives us accessible primitive behavior without forcing a product look.
- It comes from maintainers with Radix, Floating UI, Material UI, and Base UI lineage, which matters for the exact overlay/menu/focus problems desktop apps tend to hit.
Recommended experiment:
- Pick one overlay-heavy component, probably command palette or context menu.
- Rebuild it behind the same
@soma/uiexport using Base UI primitives. - Compare keyboard behavior, focus restore, animation hooks, bundle impact, and styling friction.
- Keep DaisyUI available during the experiment, but avoid new DaisyUI-only APIs.
Other Candidates
| Candidate | Fit | Concern |
|---|---|---|
| React Aria Components | Best accessibility depth and broad component coverage. | API and styling model may feel heavier than we need for a custom desktop shell. |
| Ark UI | Headless, accessible, broad component set, and a state-machine flavor that could pair well with Tapia. | Multi-framework abstraction may add concepts we do not need in a React-only Electron app. |
| Radix Primitives | Mature low-level primitives, familiar ecosystem, good fit for shadcn-style wrappers. | Base UI looks like the fresher direction for this exact unstyled React primitive layer. |
| Mantine | Very productive full component library with many hooks and ready-made controls. | More of a replacement design system than a primitive layer; likely too opinionated for @soma/ui. |
| Chakra UI | Complete component inventory and strong composability story. | Its styling/runtime model is a larger departure from Tailwind-first desktop UI. |
VitePress Compatibility
Do not add Chakra UI directly to the VitePress docs theme. Chakra UI is a React component library, while VitePress is Vue-powered. We can still document Chakra UI here as a candidate for the Electron apps, but using it inside the docs site would require a React island or iframe bridge and would add framework complexity to a content-first site.
If the docs need richer interactive examples, prefer one of these:
- Keep the VitePress shell Vue-native and link to Storybook examples under
/storybook. - Build small docs-only Vue components for simple interactivity.
- Embed a React example as an isolated iframe only when it demonstrates real
@soma/uibehavior.
Provisional Direction
Prototype Base UI inside @soma/ui first. If it feels too immature or thin for complex accessibility cases, compare the same component against React Aria Components. Avoid a wholesale framework migration until one vertical slice proves better behavior than the current DaisyUI-based implementation.