Numori UI

The design system behind all of it

Status: In developmentWhat you need: Free and openOpen-source library
Contents

The Tailwind 4 and Vue 3 component library every Numori interface is built from. Accessible, tree-shakeable, and usable in your own projects.

Being built. Not ready to install yet — the repository is public so you can follow along, and the description below is our intent rather than a finished product.

Installation

Numori UI needs Tailwind CSS v4 — the components are utility classes compiled by your app's Tailwind build. Everything else is optional.

Nuxt

The Nuxt module registers every component, so a tag such as UiButton works with no import, and only the components you reference are bundled.

Terminal
npm install numori-ui
npm install -D tailwindcss @tailwindcss/vite
nuxt.config.ts
import tailwindcss from '@tailwindcss/vite'

export default defineNuxtConfig({
  modules: ['numori-ui/nuxt'],
  css: ['~/assets/css/main.css'],
  vite: { plugins: [tailwindcss()] },
})
assets/css/main.css
@import 'tailwindcss';
@import 'numori-ui/css';

That is the whole setup: every component is registered, and only what you use is shipped.

Vite + Vue

In a plain Vite and Vue app, the plugin auto-imports components where they are referenced — no app.use, no import statements.

vite.config.js
import vue from '@vitejs/plugin-vue'
import tailwindcss from '@tailwindcss/vite'
import numoriUI from 'numori-ui/vite'

export default {
  plugins: [vue(), tailwindcss(), numoriUI()],
}

Any Vue app

With no build-tool integration, import what you use — or register a chosen set globally so unused components are still dropped.

main.js
import { createApp } from 'vue'
import { createNumoriUI, UiButton, UiModal } from 'numori-ui'
import './style.css'

createApp(App).use(createNumoriUI({ UiButton, UiModal })).mount('#app')

Styling

Styling is Tailwind CSS v4, and is deliberately not shipped as compiled CSS. The components inherit your app's Tailwind build, so there is one stylesheet, no duplication, and every token is overridable.

  • A warm neutral scale plus four semantic ramps, available as utilities (bg-primary-600) and as CSS variables (var(--color-primary-600)).
  • Dark mode is driven by a toggleable .dark class on the html element, not the prefers-color-scheme default.
  • Redeclare any token after the import to rebrand — every component picks it up, since they all reference tokens rather than literal colours.
assets/css/main.css
@import 'tailwindcss';
@import 'numori-ui/css';

@theme {
  --color-primary-400: #7c5cff; /* rebrand the accent */
  --font-sans: 'Geist', system-ui, sans-serif;
}

Icons

Icons render as inline SVG from a small bundled subset of Material Design Icons — no runtime, no network requests. If your app already has an icon system, hand rendering over to it; in Nuxt, name a globally registered component so every icon goes through Nuxt Icon.

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/icon', 'numori-ui/nuxt'],
  numoriUi: { icons: { component: 'Icon' } },
})

Tree-shaking

You ship only what you use. The build emits one module per component and declares sideEffects, so referencing three components ships three. The Nuxt module and Vite plugin are already optimal; only app.use(NumoriUI) bundles everything, so reach for createNumoriUI when size matters.

Components

18 components, grouped by what they do.

Browse all components