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

nuxt-compose-icons

v0.4.6

Published

<img width="1408" height="423" alt="Frame 207" src="https://github.com/user-attachments/assets/4f2a1f2a-57f0-49ca-bf56-075d3df9d043" />

Readme

npm version npm downloads CI bundle size license Nuxt bundle size types last commit


Nuxt-Compose-Icons

This module generates fully customizable Vue components from your initial raw SVG files at build time, and gives you:

  • 🧩 The flexibility of raw SVG
  • 🎨 Theming control:
    • At build time via configuration
    • At runtime via CSS variables
  • 🏔 ️Native Nuxt auto-import support

For building design systems or simply use in-house icons.

🎯 Motivation

Icon components should be easy to use, style, and maintain.

Existing solutions often force trade-offs between DX, accessibility, and flexibility:

  1. Third-party libraries → limited customization
  2. Manual Vue components → repetitive and hard to scale
  3. SVG loaders → flexible but lack structure and typing

The goal of this module is to propose a balanced approach which gives design flexibility and developer experience.

It dynamically generates Vue components from initial SVG files, naming them accordingly and make them accessible as individual components in the Nuxt project.

See Common Approaches.

Features

SVG to Vue Component at Build Time

  • Takes a directory of .svg files (e.g. ./assets/icons)
  • One Vue component is created per .svg file
  • Use of the initial name of the icon, converted to PascalCase or snake-case with optional prefix and suffix. Example user-badge.svg can give:
    • <IconUserBadge />
    • <UserBadgeIcon />
    • <user-badge />
  • Versioning support - optional configuration for folder-based namespacing - icon Components can directly be generated in your codebase, making the rendered icon components available as part of your codebase

Auto-Registration in Nuxt and Typing

  • Automatically registered in Nuxt’s component auto-import system (no manual registration needed) - each icon will be automatically imported and registered in the Nuxt project as individual Vue component in the tree
  • Type-safe usage in <template>

SVG Output - Accessibility

  • No wrappers - the component root element is a single <svg> element
  • No additional wrappers or nested templates
  • Attributes from the original SVG are preserved

Theming with CSS Custom Properties and Runtime Access

  • Generated components rewrite static SVG attributes (such as fill, stroke, and stroke-width) with CSS Custom Properties (CSS Custom Properties Guide) while keeping original values as fallback:
<!-- Input: user-badge.svg -->
<svg fill="#000" stroke="#fff" stroke-width="2">
  <path d="..." />
</svg>
<!-- Output: IconUserBadge.vue -->
<template>
  <svg
    fill="var(--icon-fill, #000)"
    stroke="var(--icon-stroke, #fff)"
    stroke-width="var(--icon-stroke-width, 2)"
  >
    <path d="..." />
  </svg>
</template>
  • Since CSS Custom Properties work at runtime, theming can be done dynamically in cascade (if you use design tokens), with component props or with scoped styles, giving you full control over the look of your icons.
<template>
  <div>
    <!-- Using props -->
    <IconUserBadge stroke="blue" fill="red" size="lg" />

    <!-- Using cascading styles -->
    <div class="icon-container" style="--icon-fill: red; --icon-stroke: blue;">
      <!-- Icons will inherit styles from the container -->
      <IconUserBadge />
      <!-- This icon will be red with blue stroke -->
    </div>

    <!-- Using scoped or global styles -->
    <IconUserBadge class="primary-icon" />
    <!-- This icon will use styles from the .primary-icon class -->
  </div>
</template>
<style>
.primary-icon {
  --icon-fill: var(--color-primary);
  --icon-stroke: var(--color-primary-dark);
}
</style>

Developer Experience:

  • Can provide auto-completion and type-checking in your editor for each icons, as they are directly part of the Nuxt Build like any other component
  • Vue DevTools support - unlike other solutions, this module generates Vue components that can be inspected and debugged in the Vue DevTools

This provides a balance of control, flexibility, and developer experience, tailored for projects using custom icons or building design systems.

See full list of features

Comparison with Other Icon Strategies

| Feature | Third-party Libraries | Manual Vue Components | SVG Loaders (vite-svg-loader) | Nuxt Compose Icons | | ---------------------- | ---------------------------- | --------------------- | ------------------------------- | --------------------------- | | Setup | ✅ Easy | ⚠️ Manual | ⚠️ Requires config | ✅ Minimal | | Source of truth | External package | Vue files | SVG files | SVG files | | SVG output | Clean (often wrapped) | Custom | Inline | Clean, no wrappers | | SVG control | Often abstracted | ✅ Full | ✅ Full | ✅ Full | | Theming | ⚠️ Prop-based, limited | ✅ Manual CSS | ✅ CSS-based | ✅ CSS variables + props | | Naming consistency | Library-defined | Developer-defined | File-based | Deterministic, file-based | | Typing | ✅ Provided | ✅ Manual | Depends on setup | ✅ Generated & inferred | | Scaling | Dependent on library updates | Maintenance-heavy | Flexible but unstructured | Structured, build-generated | | Nuxt integration | ✅ Works | ✅ Auto-importable | ⚠️ Requires configuration | ✅ Native auto-import |

Real-world Scenarios

| Scenario | Third-party Library | Manual Components | SVG Loader | Nuxt Compose Icons | | ------------------------------------------ | ------------------------------ | ----------------------- | -------------------------- | ------------------------------------ | | Change one color in one icon | Often limited to exposed props | Edit component manually | Modify SVG or override CSS | Override via CSS variable | | Apply global theme color | Depends on library API | Requires conventions | CSS-based | Native via CSS variables | | Preserve original SVG markup | Usually wrapped/modified | Yes | Yes | Yes | | Add a new icon | Install / import | Create component | Add file | Add file | | Rename an icon | Library-dependent | Rename file + component | Rename file | Rename file (component auto-updates) | | Maintain consistency across 100+ icons | Depends on library | Manual discipline | Flexible but unstructured | Deterministic, build-generated | | Type inference in templates | Yes | Yes | Sometimes | Yes (generated) |

Using pnpm:

pnpm add nuxt-compose-icons

Using npm

npm install nuxt-compose-icons

Using yarn

yarn add nuxt-compose-icons

🛠 Usage

Add the module to your nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['nuxt-compose-icons'],
});

Place your SVGs inside:

/assets/icons

Then use them anywhere:

<IconUserBadge/>

No imports needed.


🎯 Ideal Use Cases

  • Design systems
  • Internal product icon libraries
  • Projects requiring strict visual control
  • Teams wanting predictable DX with full styling power

Philosophy

Nuxt Compose Icons does not try to abstract SVGs away.

Instead, it embraces them:

  • Keep your structure
  • Keep your attributes
  • Just make them composable and scalable

📖 Documentation

Full documentation and advanced configuration:

👉 https://nuxt-icons.use-compose.com