flagmint-vuejs-feature-flags

A Vue.js SDK for managing feature flags in Flagmint applications, supporting both Vue 2 and Vue 3.
4,673
Install
npm install flagmint-vuejs-feature-flags
Latest Version:2.1.1
Vue:2 · 3
License:BSD-3-Clause
Last Updated:Oct 20, 2026
Links: GitHub  ·  npm
Maintainer: jtad009

Flagmint Vue Feature Flags SDK

A lightweight and powerful feature flag SDK for Vue 2 and Vue 3 applications.

Supports:

✅ Client-side flag evaluation
✅ Segment targeting and rollout strategies
✅ Server-Sent Events (SSE) or HTTP long-polling
✅ Offline caching and preview mode
✅ Vue 2 and Vue 3 plugin, composables, and helpers

🔧 Installation

npm install flagmint-vuejs-feature-flags

🚀 Quick Start

Vue 2

// main.js
import Vue from 'vue';
import { createFlagmintPlugin } from 'flagmint-vuejs-feature-flags';

Vue.use(createFlagmintPlugin({
  apiKey: 'your-api-key',
  enableFlagmint: true,
  context: { user_id: 'abc123', country: 'NG' },
  transportMode: 'auto',
  // shareConnection: true, // default when BroadcastChannel is available — one shared SSE stream; without it each client opens its own
  autoRefresh: true,
  previewMode: false
}));

new Vue({ render: h => h(App) }).$mount('#app');

Vue 3

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import { createFlagmintPlugin } from 'flagmint-vuejs-feature-flags';

const app = createApp(App);

app.use(createFlagmintPlugin({
  apiKey: 'your-api-key',
  enableFlagmint: true,
  context: { user_id: 'abc123' },
  transportMode: 'auto',
  // shareConnection: true, // default when BroadcastChannel is available — one shared SSE stream; without it each client opens its own
  previewMode: false
}));

app.mount('#app');

⚙️ API Overview

FlagClientOptions

interface FlagClientOptions {
  apiKey: string;
  enableFlagmint: boolean; // true to connect; false skips the network and evaluation cost
  context?: Record<string, any>;
  autoRefresh?: boolean;
  refreshIntervalMs?: number;
  persistContext?: boolean;
  env?: string; // production | staging
  enableOfflineCache?: boolean; // also persists signed rules when configSync is on
  cacheTTL?: number;
  transportMode?: 'auto' | 'sse' | 'long-polling';
  configSync?: boolean; // local evaluation — download signed rules and run getFlag in-process (default false)
  previewMode?: boolean;
  onError?: (err: Error) => void;
  deferInitialization?: boolean;
  shareConnection?: boolean; // js-sdk shares one SSE stream across same-origin tabs/iframes. Default: true in browsers with BroadcastChannel (false when configSync is on).
}

🎯 Using Flags

✅ Recommended (Reactive Flags)

Subscribe to flag updates so your component re-renders automatically on every SSE push:

// Vue 3 Composition API
import { useFlagmint } from 'flagmint-vuejs-feature-flags';

const { getFlag, isReady } = useFlagmint();
const darkMode = computed(() => getFlag('dark-mode', false));
// Vue 2 (via mixin)
export default {
  mixins: [useFlagsMixin],
  mounted() {
    console.log(this.flags['dark-mode']);
    console.log(this.getFlag('dark-mode', false));
  }
}

⚠️ Non-reactive (snapshot only, won't update on push)

const enabled = this.$flagmint.getFlag('dark-mode', false);

Use this only when you genuinely need a one-time read (e.g. inside a non-reactive utility function). For anything rendered in a template, use the reactive pattern above.


⏳ Await Initialization

$flagmintReady is a reactive boolean ref, not a Promise — watch it rather than awaiting it:

// Vue 2
this.$watch('$flagmintReady', (ready) => {
  if (ready) { /* client is ready */ }
});
// Vue 3
import { useFlagmintReady } from 'flagmint-vuejs-feature-flags';
const isReady = useFlagmintReady(); // Ref<boolean>
watch(isReady, (ready) => {
  if (ready) { /* client is ready */ }
});

If you need a one-time async wait (e.g. before an onMounted block runs), call the injected init() function instead — it returns a Promise that resolves once the client is ready:

const client = await this.$flagmintInit(); // Vue 2

🔌 Vue 2 Helpers

$flagmint access

export default {
  async mounted() {
    const client = await this.$flagmintInit();
    const enabled = client.getFlag('dark-mode', false);
  }
}

✅ Vue 2 Mixin

import { useFlagsMixin } from 'flagmint-vuejs-feature-flags/vue2/mixin/useFlagsMixin';

export default {
  mixins: [useFlagsMixin],
  mounted() {
    console.log(this.flags['dark-mode']);
    console.log(this.getFlag('dark-mode', false));
  }
}

🔌 Vue 3 Helpers

Option A: Composition API (Recommended)

import { useFlagmint } from 'flagmint-vuejs-feature-flags';

export default {
  setup() {
    const { getFlag, isReady, trackError } = useFlagmint();
    const feature = computed(() => getFlag('chat-enabled', false));
    return { feature };
  }
}

Option B: Injected

import { inject } from 'vue';

export default {
  setup() {
    const client = inject('__flagmint__');
    const feature = client?.getFlag('chat-enabled');
    return { feature };
  }
}

📦 Local evaluation (configSync)

By default the SDK uses server evaluation: Flagmint computes flag values and streams the results. Set configSync: true to opt into local evaluation (config sync): the stream delivers signed rules (lease / fullConfig / delta), and getFlag() evaluates in-process.

Requires Flagmint API 1.7.0+ and flagmint-js-sdk 2.2.2+ (this Vue package depends on ^2.2.2). Passed through to the JS SDK like other FlagClientOptions.

createFlagmintPlugin({
  apiKey: 'your-api-key',
  enableFlagmint: true,
  configSync: true,          // local evaluation
  enableOfflineCache: true,  // persist rules between reloads (default true)
});

Notes:

  • With configSync: true, shareConnection defaults to false (rules are not shared across tabs yet).
  • Expired lease fail-closes to defaults only until the stream refreshes rules.
  • Classic server evaluation remains the default if you omit configSync.

🔗 Connection sharing (shareConnection)

Same-origin tabs and iframes that share an API key use one SSE connection when BroadcastChannel is available (handled by flagmint-js-sdk, not Vue-level leader election). Defaults to true in those browsers (and to false when configSync is on).

createFlagmintPlugin({
  apiKey: 'your-api-key',
  enableFlagmint: true,
  shareConnection: true,  // default in browsers with BroadcastChannel (unless configSync)
  // shareConnection: false, // two clients / two contexts / two streams
});

Set shareConnection: false if two clients on the page must keep different evaluation contexts, or if the origin hosts untrusted documents.

Debugging Broadcast Channels in DevTools

To verify that multiple frames collapse to a single stream:

  • Open Chrome/Edge DevTools → Application → Background Services → Broadcast Channels.
  • Reload the page; you should see the flagmint-share:<apiKey> channel.
  • In Network, confirm only one EventSource/SSE stream opens while all views stay in sync.

🧩 Feature Component

In Vue templates, use the <BoolFeatureGate> component:

<template>
  <BoolFeatureGate featureKeys="['dark-mode']">
    <div>Dark mode is enabled!</div>
  </BoolFeatureGate>
</template>

<script setup lang="ts">
import { BoolFeatureGate } from 'flagmint-vuejs-feature-flags/vue3/Feature';
</script>

feature-keys accepts a single string or an array of strings. If multiple keys are provided, all must be enabled.

⚠️ Important: Never call client.destroy() from within a component or composable. destroy() tears down the shared SSE connection for the entire application. If you're building a custom integration around FlagClient, only ever call client.subscribe() and its returned unsubscribe function for component-level cleanup.


🧪 Preview Mode (No Network)

Enable previewMode: true in FlagClientOptions to evaluate flags locally only:

  • No API key needed
  • Useful for SDK testing, Storybook, or static environments
createFlagmintPlugin({
  previewMode: true,
  enableFlagmint: false,
  context: { user_id: 'test' }
});

You can then load flags directly:

flagClient.setFlags([flag1, flag2], segmentsById);

⚠️ A console warning appears in development when previewMode is active.


🧠 Evaluation Logic

  • Operators: eq, neq, in, nin, gt, lt, exists, not_exists

  • Segment references and rule groups

  • Rollout strategies:

    • percentage — user hashes to percentile
    • variant — weighted multi-variant assignment

🔁 Realtime Updates

Using transportMode: 'sse' or 'auto', flags update live when changed.

With transportMode: 'auto', the SDK falls back to HTTP long-polling if SSE fails. With transportMode: 'sse', no fallback occurs.


📊 Application error tracking

Call trackError after a flag was served if that variation hurt the user. The JS SDK no-ops when Analytics Tracking is off for that flag. The server also drops those events.

// Vue 3
const { getFlag, trackError } = useFlagmint();

try {
  await submitPayment();
} catch (error) {
  trackError('checkout_redesign', error, { step: 'payment' });
  throw error;
}
// Vue 2 mixin
this.trackError('checkout_redesign', error);

track(flagKey, eventName) uses the same pipe for custom metrics. Only kind: 'error' is counted in app error rate today.


📦 Versioning & Releases

This project follows Semantic Versioning. Releases are automated via GitHub Actions:

  • Changes to sdk/, package.json, rollup.config.js, or tsconfig.json on the main branch trigger the release workflow
  • The workflow extracts the version from package.json, builds the package, and publishes to npm
  • Git tags and GitHub releases are automatically created

To release a new version:

  1. Update the version in package.json
  2. Update CHANGELOG.md with your changes
  3. Push to main branch
  4. The workflow handles the rest

See CHANGELOG.md for version history and release notes.


🤝 Contributing

Contributions are welcome! Here's how to get started:

  1. Clone the repository
  2. Install dependencies: npm install
  3. Run tests: npm test
  4. Build the project: npm run build
  5. Create a feature branch: git checkout -b feature/your-feature
  6. Make your changes and commit
  7. Push to your fork and create a Pull Request

Development Tips:

  • The SDK supports both Vue 2 and Vue 3 — test changes against both versions
  • Keep bundle size in mind when adding dependencies
  • Run tests before submitting PRs
  • Never call client.destroy() from a component, mixin, or composable — only the plugin/app-level teardown should own that call

🗂 Roadmap

  • Segment evaluation
  • Rollout strategies
  • Preview/local-only mode
  • Composables and mixins
  • SSE + long-polling fallback
  • Feature component
  • SSR / Nuxt support
  • Variant analytics
  • Remote override via devtools

🐛 Troubleshooting

Flags not loading

  • Ensure apiKey is valid and environment has network access
  • Check browser console for errors
  • Verify context is properly set with required attributes
  • If using previewMode: true, ensure you've called flagClient.setFlags()

SSE connection fails

  • With transportMode: 'auto' the SDK falls back to long-polling
  • Check network connectivity and CORS settings
  • Verify the API server exposes GET /evaluator/v2/flags/stream
  • Check browser console for connection errors

Component re-renders not happening on flag updates

  • Make sure you're using the reactive pattern (useFlagmint() composable or useFlagsMixin) rather than calling client.getFlag() directly in a computed. The client's internal flag state is not a Vue reactive object — only the subscribe()-backed wrappers re-render correctly
  • If you unmounted and remounted a <BoolFeatureGate> and updates stopped working app-wide, confirm nothing in your codebase calls client.destroy() outside of app-level teardown

Stale flags in offline cache

  • Clear localStorage or set enableOfflineCache: false
  • Adjust cacheTTL to control cache duration (in milliseconds)
  • Use previewMode: true for testing without network

Performance issues

  • Limit the number of flags in targeting rules
  • Use the subscribe()-backed reactive pattern (via composable or mixin) instead of polling getFlag() in a loop
  • Consider lazy-loading flags for large applications

TypeScript issues

  • Ensure tsconfig.json includes sdk/ in include paths
  • Check that node_modules types are installed: npm install

📜 License

BSD 3-Clause License

Related Packages

@zayn919/minisentry-vue2

Mini Sentry Vue 2 SDK:Vue.config.errorHandler 适配

657
@avsbhq/vue

Vue SDK for A vs B feature flags and experiments: composables, a provider compon...

1,431 0
@avsbhq/nuxt

Nuxt module for A vs B feature flags: one line in nuxt.config, auto-imported com...

748 0
@dullar/mercury

Advanced and highly reusable Mobile UI Components built on Vue2 & You can define...

8,553 6
@halobear/vue-upload

vue上传组件

460 1

Version History

Version Released Vue License
2.1.1 ^2.7.0 || ^3.2.0 BSD-3-Clause
2.1.0 ^2.7.0 || ^3.2.0 BSD-3-Clause
2.0.0 ^2.7.0 || ^3.2.0 BSD-3-Clause
1.3.9 ^2.7.0 || ^3.2.0 BSD-3-Clause
1.3.8 ^2.7.0 || ^3.2.0 BSD-3-Clause
Pre-releases (9)
Version Released Vue License
2.1.1-rc.6 ^2.7.0 || ^3.2.0 BSD-3-Clause
2.1.1-rc.5 ^2.7.0 || ^3.2.0 BSD-3-Clause
2.1.1-rc.4 ^2.7.0 || ^3.2.0 BSD-3-Clause
2.1.1-rc.3 ^2.7.0 || ^3.2.0 BSD-3-Clause
2.1.1-rc.2 ^2.7.0 || ^3.2.0 BSD-3-Clause