How to Configure UnoCSS for Utility Classes and Global Styles in a Nuxt 4 Project

UnoCSS is configured in Nuxt 4 by installing @unocss/nuxt, creating a uno.config.ts file with shortcuts and presets, and exposing design tokens as CSS variables in a global stylesheet—exactly as implemented in the TypeWords repository.

UnoCSS is a zero-runtime, on-demand utility-first CSS engine that integrates seamlessly with Nuxt 4. In the zyronon/TypeWords project, the setup combines semantic shortcuts (reusable class aliases), CSS custom properties for theming, and transformer directives for advanced authoring patterns. This guide walks through the exact configuration used in production.

Install UnoCSS in Your Nuxt 4 Project

The TypeWords repository uses pnpm as its package manager. Install the required packages:

pnpm add -D @unocss/nuxt @unocss/preset-wind @unocss/transformer-directives

Wire the module into your Nuxt build pipeline in nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@unocss/nuxt',   // Enables UnoCSS processing
  ],
  // Additional Nuxt configuration...
})

This registration allows UnoCSS to scan your Vue files and generate utilities during the build. Reference: [nuxt.config.ts](https://github.com/zyronon/TypeWords/blob/master/nuxt.config.ts)

Create the UnoCSS Configuration File

The core configuration lives in uno.config.ts at the project root. This file defines how utilities are generated, what presets are active, and—critically—how shortcuts map to your design system.

// uno.config.ts
import { defineConfig, presetWind3, transformerDirectives } from 'unocss'

export default defineConfig({
  // ① Enable @apply-style directives in <style> blocks
  transformers: [transformerDirectives()],

  // ② Define semantic shortcuts that resolve to CSS variables
  shortcuts: {
    // Background color utilities
    'bg-primary':   'bg-[var(--color-primary)]',
    'bg-primary2':  'bg-[var(--color-primary2)]',
    'bg-second':    'bg-[var(--color-second)]',
    'bg-third':     'bg-[var(--color-third)]',

    // Composite component patterns
    'card':         'rounded-xl p-4 mb-8 shadow-lg box-border relative bg-second',
    'cp':           'cursor-pointer',
  },

  // ③ Use Tailwind-compatible preset
  presets: [presetWind3()],

  // ④ Custom responsive breakpoints
  theme: {
    breakpoints: {
      xs:   '480px',
      sm:   '640px',
      md:   '768px',
      lg:   '1024px',
      xl:   '1280px',
      '2xl': '1536px',
      '3xl': '1920px',
      '4k':  '2560px',
    },
  },
})

Reference: [uno.config.ts](https://github.com/zyronon/TypeWords/blob/master/uno.config.ts)

Key Configuration Sections

  • transformerDirectives() — Enables the @apply directive inside Vue <style> blocks, allowing you to author CSS with utility classes
  • shortcuts — Creates readable aliases that reference CSS variables; this is the bridge between UnoCSS and your design tokens
  • presets: [presetWind3()] — Provides the full Tailwind-compatible utility set without importing Tailwind CSS
  • theme.breakpoints — Defines custom responsive breakpoints used throughout the application

Define Global CSS Variables for Theming

Shortcuts in uno.config.ts reference CSS custom properties. These variables are declared in a global SCSS file: app/assets/css/main.scss.

/* app/assets/css/main.scss */
:root {
  /* Primary color palette */
  --color-primary:        #3b82f6;
  --color-primary2:       #2563eb;
  --color-second:         #f3f4f6;
  --color-third:          #e5e7eb;
  --color-fourth:         #d1d5db;
  --color-fifth:          #9ca3af;

  /* Surface colors */
  --color-card-active:    #ffffff;
  --color-item-bg:        #f9fafb;
  --color-item-border:    #e5e7eb;

  /* Text colors */
  --color-main-text:      #111827;
  --color-link:           #2563eb;
  --color-reverse-white:  #ffffff;
  --color-reverse-black:  #000000;

  /* Spacing scale */
  --space: 0.5rem;

  /* Typography families */
  --en-article-family:    'Inter', sans-serif;
  --zh-article-family:    'Noto Sans SC', sans-serif;

  /* Translation UI theme */
  --color-translate-main:   #111827;
  --color-translate-second: #6b7280;
}

The variable-driven architecture means changing --color-primary in this single file updates every component using bg-primary, text-primary, or any derived shortcut. This centralizes theming without touching component code.

Reference: app/assets/css/main.scss in the TypeWords repository.

Use Utilities and Shortcuts in Vue Components

With the configuration complete, write expressive, maintainable templates:

<template>
  <article class="card cp hover:bg-primary2 transition-colors duration-300">
    <h1 class="text-2xl font-bold color-main mb-4">
      TypeWords Practice Session
    </h1>
    <p class="color-link">
      <NuxtLink to="/settings" class="underline hover:no-underline">
        Configure preferences
      </NuxtLink>
    </p>
  </article>
</template>

How Classes Resolve

Class Generated CSS
card rounded-xl p-4 mb-8 shadow-lg box-border relative bg-[var(--color-second)]
cp cursor-pointer
hover:bg-primary2 background-color: var(--color-primary2) on :hover
color-main color: var(--color-main-text)
transition-colors transition-property: color, background-color, border-color, text-decoration-color, fill, stroke

UnoCSS scans templates at build time and emits only the used utilities, keeping runtime CSS minimal.

Extend with Custom Rules (Optional)

For patterns not covered by presets, add custom rules to uno.config.ts:

// uno.config.ts
export default defineConfig({
  // ...existing configuration

  shortcuts: {
    // Additional shortcuts
    'text-primary': 'text-[var(--color-primary)]',
    'border-item':  'border border-[var(--color-item-border)]',
  },

  // Raw pattern-to-CSS rules
  rules: [
    // Line-height utilities: lh-4, lh-6, lh-relaxed, etc.
    [/^lh-(.+)$/, ([, value]) => ({ 'line-height': value })],

    // Custom spacing based on --space token
    [/^gap-space-(\d+)$/, ([, n]) => ({ gap: `calc(var(--space) * ${n})` })],
  ],
})

These extensions integrate seamlessly with the shortcut system.

Verify Your UnoCSS Setup

  1. Start the development server

    pnpm dev
  2. Inspect generated CSS Open Chrome DevTools, select an element with a utility class, and confirm the stylesheet shows resolved CSS variables:

    .bg-primary { background-color: var(--color-primary); }
  3. Test theming Modify a variable value in main.scss and save. The browser updates instantly—no component changes required.

Summary

  • Install @unocss/nuxt and register it in nuxt.config.ts to enable build-time utility generation
  • Configure uno.config.ts with transformerDirectives, semantic shortcuts, and presetWind3 for Tailwind compatibility
  • Declare design tokens as CSS variables in app/assets/css/main.scss for centralized theming
  • Consume shortcuts in Vue templates; UnoCSS generates optimized CSS containing only used utilities
  • Extend with custom breakpoints in theme.breakpoints and additional rules for project-specific patterns

This architecture—proven in the TypeWords codebase—scales from prototypes to production while maintaining a lightweight runtime footprint.

Frequently Asked Questions

What is the difference between UnoCSS shortcuts and standard utility classes?

Shortcuts are semantic aliases you define in uno.config.ts that expand to one or more utility classes. For example, 'card': 'rounded-xl p-4 bg-second' creates a reusable component pattern. Standard utilities come from presets like presetWind3() and map directly to CSS properties. Shortcuts centralize design decisions; utilities provide atomic flexibility.

Why does TypeWords use CSS variables instead of hardcoding values in shortcuts?

CSS variables in :root enable runtime theming without rebuilds. A shortcut like bg-[var(--color-primary)] references a variable that can be updated by user preferences, dark mode toggles, or dynamic injection. Hardcoded values would require recompilation to change, breaking the separation between design tokens and component implementation.

How does transformerDirectives() improve the authoring experience?

transformerDirectives() allows the @apply directive inside Vue <style> blocks, letting you compose utilities with standard CSS syntax:

<style scoped>
.custom-button {
  @apply bg-primary text-white px-4 py-2 rounded-lg;
}
</style>

This bridges utility-first and traditional CSS authoring, useful for complex selectors or third-party component overrides.

Can I use UnoCSS with Nuxt 4's Nitro bundler?

Yes. The @unocss/nuxt module integrates at the Vite layer, which Nitro uses for client builds. The configuration in uno.config.ts is automatically picked up by both dev server and production builds. No additional Nitro configuration is required beyond the standard module registration in nuxt.config.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →