npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@brumaombra/ui-vintage

v0.8.2

Published

Source-published Nuxt UI runtime with shared theme tokens and built-in Nuxt integrations.

Readme

🎨 UI Vintage

A source-published Nuxt UI runtime for focused, reusable interfaces

@brumaombra/ui-vintage is a Nuxt 4 component library and runtime module for building consistent dashboards, forms, landing pages, overlays, and content experiences. It combines reusable Vue components, shared theme tokens, localization, and Nuxt integrations in one package that is compiled by the consuming application.

📘 Overview

UI Vintage is designed for Nuxt applications that need a coherent interface without rebuilding the same primitives for every project. The package provides low-level controls such as buttons, inputs, selects, dialogs, tabs, switches, and sidebars alongside higher-level building blocks such as dashboard shells, landing layouts, cards, data lists, and message flows.

The package is intentionally published as source. The consuming Nuxt application compiles the library together with its own runtime, which keeps Nuxt-specific integrations available and avoids maintaining a separate framework-agnostic build artifact.

This is a Nuxt library, not a generic Vue component bundle. Components rely on Nuxt runtime features including #components, NuxtImg, and module lifecycle hooks.

🖼️ Images

Screenshots

✨ Features

  • Nuxt 4 module with automatic runtime integration.
  • Shared stylesheet and design tokens injected from src/styles.css.
  • Explicit subpath imports that keep application dependencies clear.
  • Vue 3 components built with Composition API and TypeScript source.
  • Primitive UI controls based on Reka UI where accessible behavior is required.
  • Reusable dashboard, landing, blog, card, field, and data-display components.
  • Built-in busy, confirm-dialog, message-dialog, and stacked, swipeable message-toast flows.
  • A spring-based motion system (pure CSS linear() easings) that respects prefers-reduced-motion.
  • Theme selector with light, dark, and automatic modes and a circular View Transitions reveal.
  • Library locale messages merged into an existing Vue I18n instance when available.
  • Automatic @nuxt/image installation for components that use NuxtImg.
  • Source publishing with no required library build step before installation.

🏗️ Architecture

UI Vintage is split into three cooperating layers:

  • 🧩 Components in src/components/ contain the public Vue UI and composite layouts.
  • 🎨 Styles and helpers in src/styles.css and src/lib/ provide theme tokens, class utilities, and shared behavior.
  • 🔌 Nuxt runtime in module.mjs and src/runtime/ integrates the package with the consuming app.

🔄 Module Behavior

When the module is registered, it:

  1. Injects src/styles.css into the Nuxt application once.
  2. Adds the published src/ directory to Nuxt transpilation.
  3. Installs @nuxt/image when the consuming app has not already registered it.
  4. Registers the library i18n plugin.
  5. Merges the library’s locale messages into the app’s Vue I18n composer when Vue I18n is present.

The module does not auto-register every component. Import components and helpers explicitly from their public subpaths.

📁 Repository Layout

src/
  components/       # Public components and UI primitives
  i18n/              # Library locale messages
  lib/               # Shared helpers and token utilities
  runtime/           # Nuxt runtime plugins
  styles.css         # Shared design tokens and component styles
module.mjs          # Nuxt module entrypoint
demo-app/            # Private Nuxt showcase and manual verification app

🚀 Quick Start

📦 Install the package

Install the UI Vintage library and the peer integrations used by the package in an existing Nuxt 4 application:

npm install @brumaombra/ui-vintage @nuxt/image vue-i18n

🔌 Register the module

Add the module to nuxt.config.js:

export default defineNuxtConfig({
    modules: [
        '@brumaombra/ui-vintage'
    ]
});

@nuxt/image is installed by the module when it is not already present in the app’s module list. Install it explicitly when your application also uses image components directly. Vue I18n is optional at runtime, but it is required for the library’s locale messages and translated components.

🧪 Usage

🧱 Use a component

Components are imported from explicit package subpaths:

<script setup>
import { Button } from '@brumaombra/ui-vintage/button';
import { Card, CardContent } from '@brumaombra/ui-vintage/card';
</script>

<template>
    <Card>
        <CardContent class="flex items-center justify-between gap-4">
            <span>Workspace status</span>

            <!-- For example, the Button component accepts variants such as primary, secondary, gray, and ghost -->
            <Button variant="primary">Save changes</Button>
        </CardContent>
    </Card>
</template>

🔔 Use a message flow

The dialog and busy helpers can be imported directly from their subpaths:

import { showConfirmDialog } from '@brumaombra/ui-vintage/confirm-dialog';
import { setBusy } from '@brumaombra/ui-vintage/busy-indicator';

// Ask for confirmation before starting a destructive action
const confirmed = await showConfirmDialog({
    title: 'Delete project?',
    message: 'This action cannot be undone.'
});

if (confirmed) {
    // Keep the shared loading overlay visible while the request is running
    setBusy(true, { label: 'Deleting project...' });
    await deleteProject();
    setBusy(false);
}

🧭 Use a layout component

Higher-level components accept slots so application navigation and content remain app-owned. The shell provides the layout; the application provides its navigation data:

<script setup>
import { DashboardShell } from '@brumaombra/ui-vintage/dashboard-shell';

// List of sections
const sidebarSections = [{
    id: 'workspace',
    label: 'Workspace',
    items: [
        { id: 'overview', label: 'Overview', href: '/', active: true },
        { id: 'settings', label: 'Settings', href: '/settings' }
    ]
}];
</script>

<template>
    <DashboardShell :sidebar-sections="sidebarSections">
        <slot />
    </DashboardShell>
</template>

🧩 Components

The package exposes components through explicit subpaths. The complete public export map is maintained in package.json; common groups include:

🎛️ UI primitives

alert, alert-dialog, accordion, animated-number, avatar, badge, breadcrumb, button, calendar, card, checkbox, collapsible, combobox, command, data-table, date-picker, date-time-picker, dialog, dropdown-menu, field, file-dropzone, hover-card, input, kbd, label, native-select, number-field, pagination, pin-input, popover, progress, radio-group, scroll-area, select, separator, sheet, sidebar, skeleton, slider, spinner, stepper, switch, table, tabs, tags-input, textarea, time-picker, toggle-group, and tooltip.

🧱 Composite components

background-grid, card-grid, chip, dashboard-shell, data-list, empty-state-card, error-page, info-card, landing, landing-content, landing-footer, landing-navbar, landing-shell, load-more-button, loading-state-card, page-header, progress-component, single-value-card, text-link, and theme-selector.

💬 Runtime flows and integrations

busy, busy-indicator, confirm-dialog, message-dialog, message-toast, language-flag, language-selector, blog, content, and utils.

📚 Component catalog

COMPONENTS.md lists every entry point with its import line, components, props and defaults, events, slots, helpers, and usage examples. It is generated from the source and ships inside the package, so apps can always read the version they installed at node_modules/@brumaombra/ui-vintage/COMPONENTS.md.

Regenerate it after changing a public API, adding an entry point, or editing scripts/components-meta.mjs:

# Rewrite COMPONENTS.md from the source
npm run docs:components

# Fail when COMPONENTS.md is out of date (runs in the publish workflow)
npm run docs:components:check

New entry points need a description and category in scripts/components-meta.mjs; the generator fails until they have one.

🤖 AI assistant skill

The package also ships a skill that teaches coding assistants to reuse UI Vintage and to read the catalog before writing UI. To enable it in a consuming app with Claude Code, copy it into the app's skills directory:

# Copy the skill shipped with the installed version
mkdir -p .claude/skills
cp -r node_modules/@brumaombra/ui-vintage/skills/ui-vintage .claude/skills/

The skill only points to COMPONENTS.md, so it stays valid when you update the package. Copy it again only when the skill itself changes.

🎬 Motion system

src/styles.css ships a small motion vocabulary that every component uses and that apps can reuse:

  • Easing utilities: ease-spring, ease-bounce, ease-out-expo, and ease-snappy.
  • Surface utilities: uv-floating-motion (popovers, menus, tooltips), uv-modal-motion, uv-overlay-motion, uv-collapsible-motion, and uv-field (focus glow and invalid states for inputs).
  • Animations: animate-uv-pop, animate-uv-fade-up, animate-uv-shake, animate-uv-shimmer, animate-uv-float, and animate-uv-ping-soft.
  • Elevation: shadow-elevated-sm through shadow-elevated-xl, plus shadow-glow.

All durations collapse automatically when the user prefers reduced motion. Tailwind v4 animates scale, rotate, and translate as individual properties, so list those names (not transform) in custom transitions.

🖥️ Demo App

The private demo-app/ directory is a Nuxt 4 documentation-style showcase for manual verification. It is organized by category (Foundations, Actions, Forms, Data display, Navigation, Overlays, Feedback, Layouts), shows every component with a live preview and a copyable code tab, includes a live mini-app on the overview page, and has a global command palette (Ctrl/⌘ + K) to jump to any section. The navigation model lives in demo-app/app/utils/demo-navigation.ts.

The demo app is not part of the published package and is not intended to be installed by consumers. It imports the package through file:.., so it exercises the same source that is published to npm.

▶️ Run the showcase locally

From the repository root:

# Install dependencies for the demo app
npm --prefix demo-app install

# Start the Nuxt development server
npm --prefix demo-app run dev

Open the local URL printed by Nuxt. To create a production build of the showcase:

# Build the private verification app
npm --prefix demo-app run build

⚙️ Configuration

🎨 Styles

The module injects the shared stylesheet automatically. The stylesheet is also available as an explicit export when an app needs to control loading order:

// Import the shared tokens and component styles explicitly when needed
import '@brumaombra/ui-vintage/style.css';

Avoid creating a second theme-token system in the consuming app. Extend the existing CSS custom properties in your application stylesheet when a project needs additional brand values.

🌍 Localization

The package includes English, Italian, French, Spanish, German, Portuguese, Chinese, Japanese, and Russian library messages. When @nuxtjs/i18n or Vue I18n is configured, the runtime plugin merges these messages into the existing composer without replacing application messages.

Application-specific translations remain owned by the consuming app. The library only contributes messages under its own uiVintage namespace.

🧭 Imports

Use explicit subpaths for public imports:

// Import a component from its stable public entrypoint
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@brumaombra/ui-vintage/tabs';

// Import shared helper behavior from its dedicated entrypoint
import { showMessageToast } from '@brumaombra/ui-vintage/message-toast';

Do not import internal files from src/components/ in application code. Internal paths are implementation details and may change independently of public entrypoints.

📦 Publishing Model

UI Vintage publishes the Nuxt module entrypoint and source files directly:

  • module.mjs is the package entrypoint registered by Nuxt.
  • src/ contains the published components, styles, helpers, locale messages, and runtime plugin.
  • package.json defines the public component subpath exports.
  • COMPONENTS.md and skills/ ship the generated component catalog and the AI assistant skill.
  • dist/ is generated repository output and is not the source of truth for consumers.

There is no required library build step before publishing. The normal verification command is:

# Check the published TypeScript and Vue source without generating dist output
npm run typecheck

For the release process, see the project skill in .claude/skills/publish-npm/SKILL.md. The package is published under the public npm scope @brumaombra/ui-vintage.

🧰 Requirements

  • Node.js compatible with the Nuxt 4 version used by the consuming app.
  • Nuxt 4.
  • Vue 3.5 or newer.
  • @nuxt/image for image-enabled components. The module installs it when needed.
  • vue-i18n when using the library’s localization integration.

🛠️ Troubleshooting

  • Components cannot resolve Nuxt imports: confirm the app is Nuxt 4 and that @brumaombra/ui-vintage is registered in nuxt.config.js.
  • Styles are missing: check that the module is registered once and restart the Nuxt dev server after changing nuxt.config.js.
  • NuxtImg is unavailable: install @nuxt/image or allow the UI Vintage module to install it during Nuxt setup.
  • Translations do not appear: configure Vue I18n or @nuxtjs/i18n; the runtime plugin merges messages only when an i18n composer is available.
  • A component import fails: use the public subpath listed in package.json, such as @brumaombra/ui-vintage/button, rather than an internal src/ path.
  • The demo app does not start: run npm --prefix demo-app install from the repository root, then retry npm --prefix demo-app run dev.

📄 License

This project is released under the MIT License. See LICENSE for the full license text.