@nubisco/ui
v5.8.3
Published
Vue 3 UI component library
Readme
Nubisco UI
Vue 3 component library: clean, accessible, and themeable.
Table of Contents
Quick Start
npm install @nubisco/ui
# or
pnpm add @nubisco/ui
# or
yarn add @nubisco/uiLocal Development Linking
To use an unreleased build locally, link it using pnpm's link: protocol:
# 1. Build the library
cd path/to/nubisco/ui && pnpm build
# 2. Reference it in your consumer's package.json
# "@nubisco/ui": "link:../path/to/nubisco/ui"
# 3. Install
pnpm installAfter changing components in the library, run
pnpm buildagain to pick up the changes.
Icon support: If your consumer project uses NbIcon directly (not via a pre-built dist import), add the icons Vite plugin to your config. If you're importing from the pre-built dist, this is not needed because icons are bundled.
Basic Usage
Two lines of setup, after which every <Nb*> tag works in any template with no
per-file import, and the built bundle contains only what those templates used.
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { nubiscoUI } from '@nubisco/ui/vite'
export default defineConfig({
plugins: [vue(), ...nubiscoUI()],
})// main.ts
import NubiscoUI from '@nubisco/ui' // directives, command palette, app-level config
import '@nubisco/ui/css'
app.use(NubiscoUI)<template>
<NbGrid dir="col" gap="md">
<NbPanel>
<h1>Hello World</h1>
</NbPanel>
<NbButton icon="rocket-launch">Click me</NbButton>
</NbGrid>
</template>A page that renders one button and one icon links one button and one icon. The
plugin walks each template, resolves <NbButton> to an import of
@nubisco/ui/components/Button and icon="rocket-launch" to an import of
@nubisco/ui/icons/rocket-launch, and writes both into that file. Nothing is
deferred to runtime, so SSR, prerendering and hydration behave exactly as they
would with imports you had written by hand.
It also emits a components.d.ts so editors and vue-tsc still see the tags.
Without the plugin
Every component is also a real entry point, so you can import what you use:
<script setup>
import { NbButton } from '@nubisco/ui/components/Button'
import { NbGrid } from '@nubisco/ui/components/Grid'
</script>And if you cannot add a bundler plugin at all (a no-build page, a CDN embed, someone else's toolchain), there is one explicit escape hatch that registers every component globally:
import NubiscoUI from '@nubisco/ui/all'
app.use(NubiscoUI)That links the whole library, which is the cost the compile-time resolution exists to avoid. It lives behind its own import so that choosing it is a decision someone wrote down.
Vite Configuration
Add the fonts plugin to load the bundled typefaces (Plus Jakarta Sans + Fira Code), and configure SCSS so design tokens are available across all your stylesheets:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { nubiscoUI } from '@nubisco/ui/vite'
import { fonts } from '@nubisco/ui/plugins/fonts'
export default defineConfig({
plugins: [vue(), ...nubiscoUI(), fonts()],
css: {
preprocessorOptions: {
scss: {
api: 'modern-compiler',
additionalData: `@use '@nubisco/ui/variables';`,
},
},
},
})Importing Styles
Option 1: Pre-built CSS (recommended for most projects):
import '@nubisco/ui/css'Option 2: SCSS (recommended for full customization):
@use '@nubisco/ui/styles' as *;Icons and Flags
NbIcon carries ~1,500 Phosphor icons in six weights and NbFlag carries 255
country flags. No app should pay for all of them to render a handful, so the
name is resolved as early as it can be. There are three tiers, and you will
mostly use the first without thinking about it.
A literal name. The plugin sees the constant and links that one glyph:
<NbIcon name="github-logo" />
<NbIcon name="check" weight="bold" />
<NbFlag name="pt" />
<NbButton icon="plus">Add</NbButton>An imported module, for code the plugin cannot see through, and for projects that do not want a bundler plugin at all:
<script setup>
import GithubLogo from '@nubisco/ui/icons/github-logo'
</script>
<template>
<NbIcon :icon="GithubLogo" />
</template>A name only known at runtime is the interesting case: a value from an API, a CMS field, a user's choice in a picker. If the set of values it can take is known, register those modules once and the app links only them:
import { registerIcons, registerFlags } from '@nubisco/ui'
import * as check from '@nubisco/ui/icons/check'
import * as warning from '@nubisco/ui/icons/warning'
import * as pt from '@nubisco/ui/flags/pt'
registerIcons({ check, warning })
registerFlags({ pt })If it is genuinely open-ended, load the full catalogue in the one file that needs it. That file pays for it and no other page does:
import '@nubisco/ui/icons/all'
import '@nubisco/ui/flags/all'registerIcons is also how you add icons of your own, or override a built-in:
a registered name always wins over the catalogue.
If a runtime name reaches NbIcon with none of the three in place, it throws on
first render with a message naming these options, rather than silently leaving a
hole in the page.
To ship the entire collection on purpose, import both catalogues in your entry:
import '@nubisco/ui/icons/all'
import '@nubisco/ui/flags/all'What ships in your bundle covers this in full: what the plugin links for each way of naming a glyph, how to see what it resolved, and how to deliberately ship everything.
Stylesheets
The library ships one stylesheet per component rather than one 214KB file, and the plugin imports the ones each page needs alongside the components it resolved. A page with a button and an icon loads 19KB of CSS.
Design tokens are separate and always required; they come from the SCSS entry:
@use '@nubisco/ui/variables';If you would rather have the single stylesheet, turn the per-component imports off and import it yourself:
nubiscoUI({ styles: false }) // vite.config.ts
import '@nubisco/ui/css' // main.tsWhy Nubisco UI?
Most component libraries impose styling opinions that are hard to override. Nubisco UI follows a geometry-first approach where UI elements follow a grid and proportional spacing. Components are clean, accessible, and fully customisable through a comprehensive SCSS token system.
- Clean, flat design: purposeful defaults without visual gimmicks; easy to brand
- TypeScript-first: all props, events, and slots are fully typed and exported
- Tree-shakeable: ESM output with named exports; only pay for what you use
Features
- Dual build output: ES module and CommonJS bundles included
- SCSS source: full access to design tokens and variables for deep customization
- Responsive Grid: flexbox grid system with five configurable breakpoints
- Adaptive Icon System: SVG icons loaded via virtual module with zero runtime cost
- TypeScript: fully typed codebase with exported types and declaration maps
Components
Layout
| Component | Description |
| :-------- | :-------------------------------------------------------- |
| NbGrid | Responsive flexbox grid system with breakpoints |
| NbPanel | Surface container with configurable background and border |
| NbModal | Dialog overlay with focus trap and backdrop |
Form Controls
| Component | Description |
| :-------------- | :--------------------------------------------------------------------------------- |
| NbButton | Button with 5 variants (primary, secondary, ghost, danger, success), loading state |
| NbTextInput | Text input with label and validation support |
| NbNumberInput | Number input with stepper controls and min/max/step constraints |
| NbSelect | Dropdown select with search, multiple selection, and virtual scroll |
| NbCheckbox | Styled checkbox with label and indeterminate state |
| NbRadio | Radio button group with vertical/horizontal layout |
| NbSlider | Range slider with single value and range modes |
| NbColorStrip | Color strip with single/multi-select |
Actions
| Component | Description |
| :------------------ | :----------------------------------------------------------------------------------- |
| NbFloatingToolbar | Toolbar floating at an element or a plain rectangle (a text selection), focus-safe |
| NbDragHandle | Six-dot grip that reports a pointer, keyboard or native drag without owning the move |
Data Display
| Component | Description |
| :---------------------- | :------------------------------------------------------------------------------------------------------ |
| NbBadge | Status badge/pill with 7 colour variants |
| NbIcon | SVG icon component with virtual module loader |
| NbJsonTree | Collapsible JSON tree viewer |
| NbNubiscoMark | The Nubisco corporate mark, inline SVG. Also shipped as a file at @nubisco/ui/assets/nubisco-mark.svg |
| NbNubiscoPlatformMark | The Nubisco Platform product mark, inline SVG. Also at @nubisco/ui/assets/nubisco-platform-mark.svg |
Navigation
| Component | Description |
| :------------------ | :------------------------------------------------------------------------------------- |
| NbTabs | Tab bar with optional panels, line and contained variants |
| NbTableOfContents | In-page contents: nested section links, scroll-following highlight, docked or floating |
Onboarding
| Component | Description |
| :-------------- | :-------------------------------------------------------------------------------- |
| NbInfoHint | Discreet info affordance revealing a description on hover, focus or tap |
| NbWalkthrough | Guided product tour: spotlight, coach-mark popover, versioned per-user completion |
Grid System
The NbGrid component provides a flexbox-based layout system with named breakpoints:
| Name | Min-width |
| :---- | :-------- |
| sm | 320px |
| md | 672px |
| lg | 1056px |
| xl | 1312px |
| xxl | 1584px |
<NbGrid dir="row" gap="md" :grid="{ s: 12, m: 6 }">
<NbGrid dir="col">Column 1</NbGrid>
<NbGrid dir="col">Column 2</NbGrid>
</NbGrid>TypeScript Support
All component props, events, and composable types are exported:
import type {
NbGridProps,
GridType,
Breakpoint,
GridColumns,
} from '@nubisco/ui'Documentation
Full documentation is available at docs.nubisco.io/ui, including:
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for development setup, coding standards, and pull request guidelines.
All contributions require agreement to the Individual CLA: docs/CLA-INDIVIDUAL.md. By opening a pull request, you confirm your agreement under the terms in the pull request template.
Security
For security vulnerabilities, please see SECURITY.md for responsible disclosure procedures.
Support this project
If Nubisco UI is useful in your projects, consider sponsoring development. Maintaining components, design system decisions, and support takes significant time. GitHub Sponsors helps ensure long-term maintenance.
Acknowledgements
Nubisco UI draws inspiration from IBM Carbon Design System for certain component interaction patterns and documentation structure. Carbon is the work of IBM and its contributors, licensed under Apache 2.0.
