Back to Blog

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

  • Vue
  • TypeScript
  • Open Source
  • CSS
  • Themes
  • TailwindCSS
  • Dark Mode
  • WCAG
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

X / Twitter
LinkedIn
Facebook
WhatsApp
Telegram
AI Engineering for B2B

Building an AI feature your team can't finish?

Most AI projects stall because nobody on the team knows how to design agents, manage token budgets, or wire production evals. I build that layer for B2B companies so the feature actually ships and keeps shipping.

12+ years shipping production systems

Senior engineer turned AI specialist. React, Next.js, AWS, agent orchestration.

Dubai-based, working with B2B teams worldwide

Direct collaboration across UAE, Europe, and US time zones.

AI agent teams that ship, not demos that stall

Discovery, role design, MCP integration, evals, and production deployment.

About Pooya Golchian

Common questions about Pooya's work, AI services, and how to start a project together.

Get practical AI and engineering playbooks

Weekly field notes on private AI, automation, and high-performance Next.js builds. Each edition is concise, implementation-ready, and tested in production work.

Open full subscription page

Get the latest insights on AI and full-stack development.