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

> Learn to configure UnoCSS for utility classes and global styles in Nuxt 4. Explore shortcuts presets and CSS variables inspired by the TypeWords repository for efficient styling.

- Repository: [Zyronon/TypeWords](https://github.com/zyronon/TypeWords)
- Tags: how-to-guide
- Published: 2026-09-03

---

**UnoCSS is configured in Nuxt 4 by installing `@unocss/nuxt`, creating a [`uno.config.ts`](https://github.com/zyronon/TypeWords/blob/main/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](https://github.com/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:

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

```

Wire the module into your Nuxt build pipeline in **[`nuxt.config.ts`](https://github.com/zyronon/TypeWords/blob/main/nuxt.config.ts)**:

```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/main/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`](https://github.com/zyronon/TypeWords/blob/main/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.

```ts
// 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/main/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`](https://github.com/zyronon/TypeWords/blob/main/uno.config.ts) reference CSS custom properties. These variables are declared in a global SCSS file: **[`app/assets/css/main.scss`](https://github.com/zyronon/TypeWords/blob/main/app/assets/css/main.scss)**.

```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`](https://github.com/zyronon/TypeWords/blob/main/app/assets/css/main.scss) in the TypeWords repository.

## Use Utilities and Shortcuts in Vue Components

With the configuration complete, write expressive, maintainable templates:

```vue
<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`](https://github.com/zyronon/TypeWords/blob/main/uno.config.ts):

```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**
   ```bash
   pnpm dev
   ```

2. **Inspect generated CSS**
   Open Chrome DevTools, select an element with a utility class, and confirm the stylesheet shows resolved CSS variables:
   ```css
   .bg-primary { background-color: var(--color-primary); }
   ```

3. **Test theming**
   Modify a variable value in [`main.scss`](https://github.com/zyronon/TypeWords/blob/main/main.scss) and save. The browser updates instantly—no component changes required.

## Summary

- **Install** `@unocss/nuxt` and register it in [`nuxt.config.ts`](https://github.com/zyronon/TypeWords/blob/main/nuxt.config.ts) to enable build-time utility generation
- **Configure** [`uno.config.ts`](https://github.com/zyronon/TypeWords/blob/main/uno.config.ts) with `transformerDirectives`, semantic `shortcuts`, and `presetWind3` for Tailwind compatibility
- **Declare** design tokens as CSS variables in [`app/assets/css/main.scss`](https://github.com/zyronon/TypeWords/blob/main/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`](https://github.com/zyronon/TypeWords/blob/main/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:

```vue
<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`](https://github.com/zyronon/TypeWords/blob/main/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`](https://github.com/zyronon/TypeWords/blob/main/nuxt.config.ts).