Nuxt UI: the best UI library for Nuxt

The Nuxt team released their own UI library based on TailwindCSS. This, for the moment, one of the best (or the best) UI library for Nuxt. Let's check this out.

Nuxt UI: the best UI library for Nuxt

Meet the best UI library for Nuxt

Nuxt UI is an UI library that can be installed as a module for building Nuxt apps. For instance, the Volta and Nuxt studio projects are built with it.

Here's a quick overview of the library:

To get started, initialize a new Nuxt projet with the UI starter : npx nuxi init -t ui <app>

Customization made easy

If you ever used an UI library, you must have faced big roadblocks when you wanted to customize components (especially with MUI for React).

With Nuxt UI, there are three things you need to know about customization:

  • Nuxt UI relies on the App Config file to load your theme, which allows you to change it at runtime without having to restart your project.
  • Components are based on a primary and gray color that you define in the App Config file
  • You can customize components globally
  • You can customize components individually using the inline ui attribute
  • Each components' parts can be styled individually

Let's see how it works.

Customizing colors

After you've created your project, you will find the following app.config.ts file:

export default defineAppConfig({
  ui: {
    primary: 'lime',
    gray: 'neutral',
  }
})

You can use any colors from Tailwind's default colors. Try to change the primary color to orange for example and you will immediately see the change.

If you wish to add your own color, you just have to define it in your Tailwind config as usual and set it as the primary color in your app.config.ts file. 

However, you will have to provide all the shades from 50 to 950. For that you can use tools like uicolors.app, palettte.app or colorbox.io (see the tutorial here).

Customizing components globally (App Config)

Customizing your components globally allows you to customize their apparence but also their default props.

Let's say you want your buttons to be outlined by default, you can do the following:

export default defineAppConfig({
  ui: {
    button: {
      default: {
        variant: 'outline'
      },
    },
  }
})

You can do that for every props of every components.

Components are separated in multiple parts that you can find under every component's Config section. Let's take for example the Badge component; if you want to have them fully rounded by default, you can style them like this:

export default defineAppConfig({
  ui: {
     badge: {
      rounded: 'rounded-full',
    }
  }
})

You can also define default styles from different variants of your component. For example, if you want your 'solid' Buttons to have extra small text, you can do the following:

export default defineAppConfig({
  ui: {
    button: {
      variant: {
        solid: '!text-xs'
      },
    },
  }
})

Customizing components individually

Use the "ui" prop in your components to style them exactly as above, but individually. For example, if you've globally set your Badge component to be fully rounded but you want to have one particular Badge to be square, you can do the following:

<UBadge :ui="{rounded: 'rounded-none'}"></UBadge>

Powerful components

What I love about Nuxt UI's components is that you can either use props or slots or both to use them. Let me explain.

Let's say you have a simple Button with a simple icon. You can either write it this way:

<UButton icon='i-heroicons-arrow-right'>Button</UButton>

Or:

<UButton icon='i-heroicons-arrow-right' label="Button">

Or:

<UButton label="Button">
 <template #leading>
   <UIcon name="i-heroicons-arrow-right"/>
 </template>
</UButton>

This provides a lot of flexibility with pre-built components. Instead of an icon, you could display an Avatar component for instance:

<UButton label="Button">
  <template #leading>
    <UAvatar
      src="https://avatars.githubusercontent.com/u/739984?v=4"
      size="3xs"
    />
  </template>
</UButton>

I won't list all components, just check out their documentation and have fun playing with them.

100,000+ Icons at your disposal

Never get out of icons anymore. Thanks to Iconify, you can use any icons you want in any components with the following format: i-{collection_name}-{icon_name}

Some components have an icon prop that allows you to add an icon to the component, like the Button component we saw earlier. You can also use the UIcon component and pass it an icon name using the name prop.

What's great is that Nuxt UI uses will not fetch any icon from the web, but will only bundle the icons you use in your app thanks to @egoist/tailwindcss-icons.

By default, Nuxt UI uses Heroicons but you can change it from your nuxt.config.ts file:

export default defineNuxtConfig({
  ui: {
    icons: ['mdi', 'simple-icons']
  }
})

To do that, you must install icon packages individually (@iconify-json/{collection_name}) or the @iconify/json package (full icon collections, 50MB)

If you're using @iconify/json, you can do the following inside your nuxt.config.ts file:

export default defineNuxtConfig({
  ui: {
    icons: 'all'
  }
})

But be careful: from my experience your development server will boot up slower if you do that.

Conclusion

To be honest, it's so refreshing to see that kind of UI library for Nuxt.

Everything works right from the start, and the DX experience is incredibly smooth. As an added bonus, the library is crafted by the NuxtLabs team themselves.

Enjoy your coding!