@itguy614/clean-ui

A clean, dark-mode-ready Vue 3 component library — 100+ token-driven, themeable, accessible components.
2,243
Install
npm install @itguy614/clean-ui
Latest Version:1.5.1
Vue:3
License:MIT
Last Updated:Oct 23, 2026
Links: GitHub  ·  npm
Maintainer: kurt.wolf

@itguy614/clean-ui

npm license docs

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 / CuiRounded prop 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 @theme so 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

@sabrenski/spire-ui-vue

A modern, themeable Vue 3 component library with 57+ components, TypeScript supp...

42,505
@cocoar/vue-ui

Cocoar Design System — a touch-first Vue 3 component library with 30+ accessible...

17,724 0
@hina-ui/vue

The design system behind Hikarinagi: Vue 3 components built on Tailwind CSS v4.

4,608 10
@bobbykim/manguito-theme

main theme file for manguito components library. Other MCL components will need...

3,458 3
@abelfuentes/ui-controls

Componentes UI atómicos como Web Components. Sin dependencias; funcionan en Reac...

1,057 0

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