@itguy614/clean-ui
@itguy614/clean-ui
A clean, dark-mode-ready Vue 3 component library. 100+ components built on a fully token-driven theme system — subtle by default, bold by choice, accessible first, and overridable at every level via CSS custom properties.
📖 Documentation & live examples →
Features
- 100+ components — layout, form controls, actions, feedback, data display, navigation, and overlays.
- 8 built-in themes + light/dark mode, all driven by
--cui-*custom properties you can override on any scope. - Accessible first — WCAG AA contrast targets, ARIA attributes, keyboard navigation, focus management.
- TypeScript — full type definitions; shared
CuiColor/CuiSize/CuiRoundedprop types across components. - Works with or without Tailwind — no Tailwind needed in your app; if you use Tailwind CSS v4, the color scales are registered via
@themeso its utilities match the components. - Tree-shakeable, per-module ESM — Vue is the only peer dependency. (ESM-only as of 1.0.)
Installation
npm install @itguy614/clean-ui
# peer dependency
npm install vue@^3.5
Quick start
Register the plugin (registers every Cui* component globally) and import the stylesheet once:
// main.ts
import { createApp } from "vue";
import { createCleanUI } from "@itguy614/clean-ui";
import "@itguy614/clean-ui/styles";
import App from "./App.vue";
createApp(App).use(createCleanUI()).mount("#app");
<template>
<CuiButton color="primary" variant="solid">Click me</CuiButton>
</template>
Tailwind is optional. import "@itguy614/clean-ui/styles" is everything Clean-UI
needs: it ships its own compiled CSS and builds no classes in your app. Use Tailwind for
your own markup if you like, but don't add Clean-UI's dist to Tailwind's @source.
Scanning it gains nothing and can add unused utilities to your CSS.
The stylesheet does not reset your page
@itguy614/clean-ui/styles styles the library's own components and nothing else.
Its base rules — box-sizing, font: inherit on form controls, list and margin
resets — are scoped to elements carrying a cui-* class and their descendants,
and every selector sits at zero specificity (:where(…)), so your own CSS always
wins. Nothing is applied to html, body, or your markup.
That means the library does not supply a global reset. If you use Tailwind,
your own @import "tailwindcss" already provides preflight. If you don't, and you
want one, bring your own (normalize.css, modern-normalize, or your framework's).
Or import components individually
No plugin required — import only what you use:
<script setup lang="ts">
import { CuiButton, CuiCard, CuiCardBody } from "@itguy614/clean-ui";
import "@itguy614/clean-ui/styles";
</script>
<template>
<CuiCard>
<CuiCardBody>
<CuiButton>Hello</CuiButton>
</CuiCardBody>
</CuiCard>
</template>
Theming
Eight presets ship out of the box: Navy (default), Mono, Forest, Amber, Azure, Teal, Violet, and Ruby.
Themes are plain CSS classes — apply one to any ancestor (or <html>) and everything inside re-themes:
<html class="cui-theme-forest"> <!-- whole app -->
<div class="cui-theme-violet"> … </div> <!-- scoped subtree -->
Dark mode is the dark class on any ancestor:
<html class="dark cui-theme-azure"> … </html>
Switch themes reactively with the useTheme composable (persists to localStorage):
import { useTheme } from "@itguy614/clean-ui";
const { theme, setTheme } = useTheme();
setTheme("forest");
Customizing tokens
Every color, radius, and typography value is a --cui-* custom property. Override on :root or any scoped container:
:root {
--cui-button-radius: 0.5rem;
}
/* Or re-map a whole color scale for a custom brand theme */
.cui-theme-brand {
--color-primary-500: oklch(0.5 0.2 320);
/* …50–950 */
}
Markdown editor
Need a markdown editor? The companion package
@itguy614/clean-ui-editor
is a CodeMirror 6 editor themed with clean-ui's tokens — WYSIWYG (hidden syntax markers) and
source modes, a declarative plugin API, and an optional safe HTML renderer. It has a heavier
dependency graph, so it ships as a separate, lazily-loadable package rather than in the core:
npm install @itguy614/clean-ui-editor
<script setup lang="ts">
import { ref, defineAsyncComponent } from "vue";
import "@itguy614/clean-ui-editor/styles";
const CuiMarkdownEditor = defineAsyncComponent(() =>
import("@itguy614/clean-ui-editor").then((m) => m.CuiMarkdownEditor),
);
const content = ref("# Hello");
</script>
<template>
<CuiMarkdownEditor v-model="content" />
</template>
See the editor README for modes, plugins, and rendering.
Documentation
Full component reference, props, and live examples: https://itguy614.github.io/clean-ui/
License
MIT © Kurt Wolf
Related Packages
A modern, themeable Vue 3 component library with 57+ components, TypeScript supp...
Cocoar Design System — a touch-first Vue 3 component library with 30+ accessible...
The design system behind Hikarinagi: Vue 3 components built on Tailwind CSS v4.
main theme file for manguito components library. Other MCL components will need...
Componentes UI atómicos como Web Components. Sin dependencias; funcionan en Reac...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.5.1 | ^3.5.0 | MIT | |
| 1.5.0 | ^3.5.0 | MIT | |
| 1.4.0 | ^3.5.0 | MIT | |
| 1.3.2 | ^3.5.0 | MIT | |
| 1.3.1 | ^3.5.0 | MIT | |
| 1.3.0 | ^3.5.0 | MIT | |
| 1.2.2 | ^3.5.0 | MIT | |
| 1.2.1 | ^3.5.0 | MIT | |
| 1.2.0 | ^3.5.0 | MIT | |
| 1.1.0 | ^3.5.0 | MIT | |
| 1.0.1 | ^3.5.0 | MIT | |
| 1.0.0 | ^3.5.0 | MIT | |
| 0.9.0 | ^3.5.0 | MIT | |
| 0.3.1 | ^3.5.0 | MIT | |
| 0.1.0 | ^3.5.0 | MIT |