Light and Dark Themes

This page explains the baseline theming behavior that Nuvex UI already brings into your app. Use it to adopt the built-in light and dark themes correctly before you move to runtime controls or custom themes.

What the framework already gives you

  • Nuvex UI always registers light and dark as built-in themes.
  • The theme plugin is optional. A project can stay on the built-in baseline and still have a complete theming setup.
  • If you only need to refine how light or dark look, the normal path is Design Tokens or CSS Variables, not a new named theme.

Built-in theme baseline

The framework starts with a real baseline, not an empty hook. Light and dark are always present, carry the official surface hierarchy, and are the default starting point for almost every product integration.

  • Light and dark are already registered before you add any custom theme.
  • The built-in surface hierarchy is shared across both themes and acts as the framework default visual baseline.
  • You can ship a complete app without registering another named theme if the product only needs the built-in model.

Initial theme resolution

The initial theme is resolved in a strict order: persisted value first, then system preference, then configured defaultTheme, and finally the built-in fallback. This matters when the app seems to start in a different theme than the one you expected.

If your startup behavior is wrong, check the resolution order before adding more runtime logic. Most mismatches come from storage or system preference winning earlier than defaultTheme.

1. Persisted theme wins first

If storage is enabled and it returns a registered theme, Nuvex UI starts there before checking anything else.

2. System preference wins next

If there is no stored theme and system detection is enabled, prefers-color-scheme resolves to light or dark when those themes exist.

3. defaultTheme is only the next fallback

defaultTheme is used after storage and system preference, not before them.

4. Built-in light is the final safety net

If nothing else resolves and light exists, the framework falls back to light as the last baseline.

DOM theme contract

When a theme becomes active, Nuvex UI writes the theme attribute to documentElement and, when isDark is known, also applies the corresponding color-scheme. This is the contract your app CSS and theme-specific selectors consume.

app/assets/styles/theme.css

Adopt light and dark in Vue and Nuxt

The normal setup is small: keep the built-in themes, choose whether storage and system preference are enabled, and define defaultTheme only when the product needs a different startup baseline.

This page is about consuming the built-in baseline. If the next task is toggling, persisting, or reacting to theme changes from components, continue with Runtime Theme API.

app/plugins/nuvex-ui.ts

nuxt.config.ts

Customize light and dark without creating a new theme

Use Sass tokens to change the framework baseline at build time, or CSS variables when the override belongs in the cascade. Do not try to re-register light or dark through theme options just to restyle them.

Built-in themes are not replaced through the plugin themes registry. Their visual customization belongs to Design Tokens and CSS Variables.

When to stay on the base themes

Stay on light and dark when the product still fits the built-in theme model and only needs visual refinement. Move to custom themes only when you need an additional named variant with its own identity and runtime selection path.

Move to custom themes only when the product needs another named runtime option. If the need is only visual refinement, keep light and dark and customize the baseline instead.

Recommended next steps

Continue with the page that matches the next real theming change after the built-in baseline is stable.