Back to Blog

vue-multiple-themes v4: Dynamic Multi-Theme Support for Vue 2 & 3

VueTypeScriptOpen SourceCSSThemesTailwindCSSDark ModeWCAG
Abstract visualization of multiple color themes applied to a Vue.js application

I have been building UIs with Vue for years and one pattern comes up constantly — you need more than dark/light. Clients want seasonal themes, brand-specific palettes, and accessibility-compliant contrasts. I extracted all of that into a standalone, typed library: vue-multiple-themes.

Full Documentation & Demo

What It Solves

The standard approach is toggling a .dark class on <html> and writing a wall of CSS overrides. That works for two themes. Scale to three or more and you get duplicated selectors, fragile specificity battles, and no tooling for generating accessible palettes.

vue-multiple-themes replaces that with:

  • CSS custom properties (--vmt-*) injected at the target element — every theme is a swap of values at one cascade layer
  • A reactive useTheme() composable accessible anywhere in the component tree
  • 7 preset themes ready to use immediately
  • A TailwindCSS plugin that exposes those tokens as Tailwind utilities
  • WCAG color utilities for contrast checking, mixing, and palette generation — all SSR-safe

Installation

bash
pnpm add vue-multiple-themes

Requires Vue 2.7+ or Vue 3. Zero runtime dependencies beyond Vue itself.

Quick Start — Vue 3

Register the plugin once in main.ts:

typescript
import { createApp } from 'vue'; import { VueMultipleThemesPlugin } from 'vue-multiple-themes'; import App from './App.vue'; const app = createApp(App); app.use(VueMultipleThemesPlugin, { defaultTheme: 'dark', strategy: 'attribute', persist: true, }); app.mount('#app');

Then use useTheme() anywhere:

vue
<script setup lang="ts"> import { useTheme, PRESET_THEMES } from 'vue-multiple-themes'; const { currentTheme, setTheme, themes } = useTheme({ themes: PRESET_THEMES }); </script> <template> <button v-for="t in themes" :key="t.name" @click="setTheme(t.name)"> {{ t.label }} </button> </template>

CSS Custom Properties

Once a theme is active, --vmt-* variables are available on <html>. Style components against them:

css
.card { background: var(--vmt-background); color: var(--vmt-foreground); border: 1px solid var(--vmt-border); }

Switching themes updates every component instantly — no re-renders required.

The 7 Preset Themes

NameCharacter
lightClean white + indigo
darkDark gray + violet
sepiaWarm parchment browns
oceanDeep sea blues
forestRich greens
sunsetWarm oranges & reds
winterIcy blues & whites

Dynamic Theme Generation

typescript
import { generateThemePair, generateColorScale } from 'vue-multiple-themes'; const { light, dark } = generateThemePair('#6366f1'); const scale = generateColorScale('#6366f1', 9);

Ideal for SaaS products where each tenant sets a brand color and the full UI adapts automatically.

TailwindCSS Integration

javascript
const { createVmtPlugin } = require('vue-multiple-themes/tailwind'); module.exports = { plugins: [createVmtPlugin()] };
html
<div class="bg-vmt-surface text-vmt-foreground border-vmt-border"> Themes itself automatically on switch </div>

WCAG Utilities

Pure functions — no DOM, fully SSR-safe, tree-shakeable:

typescript
import { contrastRatio, autoContrast, checkContrast, lighten, darken } from 'vue-multiple-themes'; contrastRatio('#6366f1', '#ffffff'); // 4.54 autoContrast('#6366f1'); // '#ffffff' checkContrast('#6366f1', '#ffffff'); // { ratio: 4.54, aa: true, aaa: false, aaLarge: true, aaaLarge: true }

useTheme() API

OptionTypeDefaultDescription
themesThemeDefinition[]preset listAvailable themes
defaultThemestringlightInitial theme
strategyattribute / class / bothattributeDOM application strategy
persistbooleantrueSave to localStorage
storageKeystringvmt-themelocalStorage key

Returns: { currentTheme, currentName, themes, setTheme, nextTheme, prevTheme }

Vue 2 Support

javascript
import Vue from 'vue'; import { VueMultipleThemesPlugin } from 'vue-multiple-themes'; Vue.use(VueMultipleThemesPlugin, { defaultTheme: 'light' });

GitHub · npm · Full Documentation

pooya.blog

vue-multiple-themes v4: Dynamic Multi-Theme Support for Vue 2 & 3

A deep dive into vue-multiple-themes v4 — the open source library for dynamic CSS custom property theming in Vue 2.7+ and Vue 3. Covers the useTheme() composable, TailwindCSS plugin, WCAG contrast utilities, and dynamic…

https://pooya.blog/blog/vue-multiple-themes

X / Twitter
Share
vue-multiple-themes v4: Dynamic Multi-Theme Support for Vue 2 & 3

A deep dive into vue-multiple-themes v4 — the open source library for dynamic CSS custom property theming in Vue 2.7+ and Vue 3. Covers the useTheme()…

https://pooya.blog/blog/vue-multiple-themes
LinkedIn
Share
vue-multiple-themes v4: Dynamic Multi-Theme Support for Vue 2 & 3

A deep dive into vue-multiple-themes v4 — the open source library for dynamic CSS custom property theming in Vue 2.7+ and Vue 3. Covers the useTheme() composable, TailwindCSS plugin, WCAG contrast utilities, and dynamic theme generation from a single brand color.

🔗 https://pooya.blog/blog/vue-multiple-themes
Facebook
Share
vue-multiple-themes v4: Dynamic Multi-Theme Support for Vue 2 & 3

A deep dive into vue-multiple-themes v4 — the open source library for dynamic CSS custom property theming in Vue 2.7+ and Vue 3. Covers the useTheme()…

https://pooya.blog/blog/vue-multiple-themes
WhatsApp
Share
*vue-multiple-themes v4: Dynamic Multi-Theme Support for Vue 2 & 3*

_A deep dive into vue-multiple-themes v4 — the open source library for dynamic CSS custom property theming in Vue 2.7+ and Vue 3. Covers the useTheme()…_

https://pooya.blog/blog/vue-multiple-themes
Telegram
Share
vue-multiple-themes v4: Dynamic Multi-Theme Support for Vue 2 & 3

A deep dive into vue-multiple-themes v4 — the open source library for dynamic CSS custom property theming in Vue 2.7+ and Vue 3. Covers the useTheme()…

https://pooya.blog/blog/vue-multiple-themes

Common Questions

Answers to questions I hear most often from potential clients and collaborators.