Skip to content

Reference

TypeScript types

All public types are exported from the package root:

ts
import type {
  FeatureTogglesOptions,
  FeatureProvider,
  FlagSource,
  FlagValue,
  FlagMeta,
  FlagName,
  SetFlagOptions,
  LiveUpdatesOptions,
} from 'vue-feature-toggles'
ts
// FlagValue is boolean OR a variant string
type FlagValue = boolean | string

// All flag source tiers
type FlagSource = 'url' | 'runtime' | 'rules' | 'loader' | 'static' | 'default'

interface FlagMeta {
  description?: string
  owner?: string
  addedAt?: string // ISO date string, e.g. '2025-03-01'
  ticket?: string
}

interface SetFlagOptions {
  persist?: boolean // save to localStorage
}

interface LiveUpdatesOptions {
  type: 'sse' | 'websocket'
  url: string
  reconnectDelay?: number // ms, default: 3000
}

// FlagName resolves to a union of your declared flag names when FeatureFlagNames is augmented,
// or falls back to string when it is empty.
type FlagName = keyof FeatureFlagNames extends never ? string : keyof FeatureFlagNames

Type safety

Extend the built-in FeatureFlagNames interface to get autocomplete and compile-time errors on flag names everywhere — useFeature, setFlag, isEnabled, <Feature name="...">, etc.

ts
// feature-flags.d.ts (or any .d.ts file in your project)
declare module 'vue-feature-toggles' {
  interface FeatureFlagNames {
    newDashboard: true
    betaSearch: true
    darkMode: true
  }
}
ts
useFeature('newDashbord') // TS error: Argument of type '"newDashbord"' is not assignable
useFeature('newDashboard') // ✔

Exports

ts
// Main entry — vue-feature-toggles
import {
  FeatureToggles, // plugin for app.use()
  Feature, // <Feature> component
  FeatureVariant, // <FeatureVariant> component
  FeatureDevTools, // DevTools overlay component
  vFeature, // v-feature directive
  useFeature, // composable
  useFeatureVariant, // composable for variant flags
  useFeatureProvider, // low-level composable
  FEATURE_PROVIDER_KEY,
} from 'vue-feature-toggles'

import type {
  FeatureTogglesOptions,
  FeatureProvider,
  FlagSource,
  FlagValue,
  FlagMeta,
  FlagName,
  SetFlagOptions,
  LiveUpdatesOptions,
} from 'vue-feature-toggles'

// Testing utilities (excluded from production bundle)
import {
  createTestFeatureProvider,
  withFeatures,
  setTestFlag,
  resetTestProvider,
} from 'vue-feature-toggles/testing'

// Storybook decorator (excluded from production bundle)
import { withFeatureToggles } from 'vue-feature-toggles/storybook'

// Adapter loaders (LaunchDarkly, Unleash, Flagsmith)
import { launchDarklyLoader, unleashLoader, flagsmithLoader } from 'vue-feature-toggles/adapters'

// Vite plugin — strips <FeatureDevTools> in production builds
import { featureTogglesPlugin } from 'vue-feature-toggles/vite'

// Nuxt module
// modules: ['vue-feature-toggles/nuxt']

Architecture

vue-feature-toggles

├── FeatureProvider  (core singleton, created by the plugin)
│     FlagStore        — Map<name, FlagValue>; reactive via shallowRef
│     SourceIndex      — Map<name, FlagSource>; priority tier per flag
│     VariableStore    — Map<flagName+varName, Ref<T>>
│     ProfileStore     — reads/writes named snapshots to localStorage

├── Priority chain  (highest → lowest)
│     UrlOverrideLayer   — reads query params on init; reactively updates via URLSearchParams
│     RuntimeLayer       — setFlag() / setVariant() / setVariable(); persist option → localStorage
│     RulesLayer         — watches reactive rule functions; re-evaluates when deps change
│     LoaderLayer        — async loader; optional polling via setInterval; live update listener
│     StaticLayer        — flags/variables from plugin options
│     DefaultLayer       — defaultValue fallback

├── DependencyManager
│     Computes forced-off flags when required flags are disabled
│     Emits dev-console warnings on violation; exposes getDependencyViolations()

├── GroupManager
│     setGroup() fans out to all member flags via RuntimeLayer
│     isGroupEnabled() checks all members synchronously

├── ExpiryManager
│     Compares meta.expiry dates against Date.now() on every isEnabled() call
│     Expired flags return defaultValue; dev-console warning on first access

├── LiveUpdatesManager
│     SSE — EventSource; auto-reconnect on error
│     WebSocket — native WebSocket; configurable reconnectDelay
│     Both merge the received partial flags object into LoaderLayer

├── <Feature> / <FeatureVariant>
│     Inject FEATURE_PROVIDER_KEY; render via computed isEnabled / getVariant
│     Loading slot shown while isLoading.value is true

├── v-feature directive
│     beforeMount + updated hooks; sets el.style.display based on flag value

├── useFeature / useFeatureVariant
│     Thin wrappers returning computed Refs from FeatureProvider

├── <FeatureDevTools>
│     Three-tab overlay: Flags · Groups · History
│     Draggable via mousedown + mousemove; position persisted in sessionStorage
│     Reads/writes directly via useFeatureProvider()

├── DevTools integration  (optional @vue/devtools-api)
│     Loaded dynamically; silently skips if package absent
│     Inspector: all flags with source badges
│     Timeline: flag change events with prev/next value

├── /testing  (separate entry point)
│     createTestFeatureProvider — isolated FeatureProvider, no localStorage side-effects
│     withFeatures — @vue/test-utils mount options shorthand
│     setTestFlag — sets flag + awaits nextTick
│     resetTestProvider — clears all runtime overrides

├── /storybook  (separate entry point)
│     withFeatureToggles — Storybook decorator; merges story parameters on top of global defaults

├── /adapters  (separate entry point)
│     launchDarklyLoader, unleashLoader, flagsmithLoader
│     Each returns an async () => Record<string, FlagValue> compatible with the loader option

├── /vite  (separate entry point)
│     featureTogglesPlugin — Vite transform that removes <FeatureDevTools> in production

└── /nuxt  (module)
      Registers <Feature>, <FeatureVariant>, v-feature globally via addComponent / addDirective
      Installs plugin via addPlugin with runtimeConfig.featureToggles
      Handles SSR state via nuxtApp.payload (no ssrState config needed)

Bundle size & peer dependencies

Entry pointPeer depsNotes
vue-feature-togglesvue ^3.0Core — plugin, components, directive, composables
vue-feature-toggles/testingvue ^3.0Test helpers only; excluded from prod bundle
vue-feature-toggles/storybookvue ^3.0Storybook decorator only; excluded from prod
vue-feature-toggles/adaptersvue ^3.0LaunchDarkly, Unleash, Flagsmith loaders
vue-feature-toggles/vitevite ^4Vite transform plugin
vue-feature-toggles/nuxtvue ^3.0, @nuxt/kit (optional peer)Nuxt 3 module

The package ships as tree-shakeable ESM (dist/*.js) and CommonJS (dist/*.cjs). @vue/devtools-api is an optional peer dependency — the DevTools integration is loaded dynamically and silently skipped when the package is absent or when Vue DevTools are closed.

License

MIT