Skip to content

Installation

Install bitboss-ui 3, wire up the two plugins, and render your first component.

On this page

v3 is a plugin, not a bag of exports. You always install two pieces. The build plugin generates the config, the icon registry and the typed variant lists. The runtime plugin injects the styles and registers the directives. Skip either one and components render unstyled or throw on an icon name.

Install the package

bash
npm install bitboss-ui@beta
npm install -D @iconify-json/lucide

Confirm what you got before going further:

bash
npm ls bitboss-ui   # must report 3.0.0-*

@latest is the v2 line, and stays that way until v3 goes stable.

Vue ^3.5.12 is the only required peer. @inertiajs/vue3 is optional and needed only in Inertia apps; vee-validate only if you use the validated form controls.

The build plugin

Nuxt. The module wraps the Vite plugin and registers the runtime plugin for you, so you write no app.use:

ts
// nuxt.config.ts
export default defineNuxtConfig({
    modules: ['bitboss-ui/nuxt'],
    bitboss: {
        // see the icons section — the default is almost certainly what you want
    },
});

Vite. Add the plugin, then install the runtime plugin yourself:

ts
// vite.config.ts
import { bitbossUi } from 'bitboss-ui/vite';

export default defineConfig({
    plugins: [vue(), bitbossUi({})],
});

You configure everything here, at build time. Only locale stays editable at runtime, through useBbConfig().

Styles and the runtime plugin

In Nuxt, add the stylesheet to css and the module does the rest:

ts
// nuxt.config.ts
css: ['bitboss-ui/styles.css'],

Everywhere else, install the runtime plugin and import the styles once, at the entry point:

ts
// main.ts
import { createApp } from 'vue';
import { bitbossUiPlugin } from 'bitboss-ui';
import 'bitboss-ui/styles.css';
import App from './App.vue';

createApp(App).use(bitbossUiPlugin).mount('#app');

The runtime plugin is what registers v-bb-tooltip, v-bb-dropdown, v-bb-color, v-bb-date and v-bb-time. Without it those directives throw.

bitboss-ui/reset.css is optional and separate. Take it only if you are not already running a reset of your own.

Icons

Icon names are provider-first: lucide:plus resolves from the installed @iconify-json/* package, and local:logo resolves from your own SVG directory.

iconDir defaults to ./assets/icons, resolved relative to your source directory. In Nuxt 4 that is app/, so the default already means app/assets/icons.

Change it only if your icons genuinely live elsewhere, and write the path relative to the source directory:

ts
bitboss: {
    iconDir: './assets/icons', // = app/assets/icons in Nuxt 4
}

Drop an SVG in that directory and it is available as local:<filename>.

Imports and the type gate

Import components explicitly:

vue
<script setup lang="ts">
import { BbButton, BbSelect } from 'bitboss-ui';
</script>

There is no auto-import to turn on. The Nuxt module registers the Vite plugin and the runtime plugin, and nothing else. Explicit imports are what let this catch a mistyped or removed component at type-check time:

json
// tsconfig.json
{
    "vueCompilerOptions": {
        "checkUnknownComponents": true
    }
}

With auto-imports on, every Bb* tag would resolve and that gate would go quiet. This documentation site relies on it to catch a v2 prop surviving in an example.

Your first component

vue
<template>
    <BbSelect
        id="assignee"
        v-model="assignee"
        label="Assignee"
        item-text="fullName"
        item-value="id"
        :items="users"
    />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { BbSelect } from 'bitboss-ui';

const assignee = ref<number | null>(null);
const users = [
    { id: 1, fullName: 'Ada Okonkwo' },
    { id: 2, fullName: 'Luca Ferrari' },
];
</script>

label is required: it is the accessible name. Pass items your domain objects as they are, then name the display field and the stored value. You never map them to { label, value } pairs first.

Where to go next

Choose the next page by task: