Nuxt Feature Flags 🚩

A powerful, type-safe feature flag module for Nuxt 3 that enables both static and dynamic feature flag evaluation with server-side support. Perfect for A/B testing, gradual rollouts, and feature management.
✨ Features
- 🎯 Context-aware evaluation: Evaluate flags based on request context (user roles, geo-location, device type, etc.)
- 🛠 TypeScript Ready: Full TypeScript support with type-safe flag definitions and autocomplete
- 🔍 Explanation System: Understand why flags are enabled/disabled with detailed explanations
- 🧩 Nuxt 3 Integration: Seamless integration with auto-imports and runtime config
- 🎯 Static & Dynamic Flags: Support for both simple boolean flags and dynamic evaluation
- 🔒 Type Safety: Catch errors early with full type inference and validation
📦 Installation
npx nuxi module add nuxt-feature-flags
npm install nuxt-feature-flags
yarn add nuxt-feature-flags
pnpm add nuxt-feature-flags
🚀 Quick Setup
- Add the module to your
nuxt.config.ts
:
Basic usage providing plain configuration.
export default defineNuxtConfig({
modules: ['nuxt-feature-flags'],
featureFlags: {
flags: {
newDashboard: false,
experimentalFeature: true
}
}
})
Basic usage providing configuration file.
export default defineNuxtConfig({
modules: ['nuxt-feature-flags'],
featureFlags: {
config: './feature-flags.config.ts',
}
})
Advance usage providing context based flag rules (Only for api route requests).
import type { H3EventContext } from 'h3'
export default function featureFlagsConfig(context?: H3EventContext) {
return {
isAdmin: context?.user?.role === 'admin',
newDashboard: true,
experimentalFeature: process.env.NODE_ENV === 'development',
promoBanner: false,
betaFeature: false,
}
}
- Use in your Vue components:
<script setup>
const { isEnabled, get } = useClientFlags()
</script>
<template>
<div>
<NewDashboard v-if="isEnabled('newDashboard')" />
<div v-if="get('experimentalFeature')?.explanation">
Flag enabled because: {{ get('experimentalFeature').explanation.reason }}
</div>
</div>
</template>
- Use in your server routes:
export default defineEventHandler((event) => {
const { isEnabled } = await useServerFlags(event)
if (!isEnabled('newDashboard')) {
throw createError({
statusCode: 404,
message: 'Dashboard not available'
})
}
return {
stats: {
users: 100,
revenue: 50000
}
}
})
📖 Documentation
Visit our documentation site for detailed guides and API reference.
Client-Side Usage
const {
flags,
isEnabled,
get
} = useClientFlags()
if (isEnabled('newFeature')) {
}
const flag = get('experimentalFeature')
console.log(flag.explanation)
Server-Side Usage
const {
flags,
isEnabled,
get
} = await useServerFlags(event)
if (isEnabled('newFeature')) {
}
const flag = get('experimentalFeature')
console.log(flag.explanation)
Flag Types
interface Flag<T = boolean> {
value: T
explanation?: {
reason: 'STATIC' | 'TARGETING_MATCH' | 'DEFAULT'
rule?: string
}
}
⚙️ Configuration
interface FeatureFlagsConfig {
flags?: FlagDefinition
config?: string
}
type FlagDefinition = Record<string, boolean>
export default defineNuxtConfig({
featureFlags: {
flags: {
promoBanner: true,
betaFeature: false,
newDashboard: false
}
}
})
export default {
isAdmin: false,
newDashboard: true,
experimentalFeature: true,
promoBanner: false,
betaFeature: false,
}
export default defineNuxtConfig({
featureFlags: {
flags: {
config: './feature-flags.config.ts',
}
}
})
🤝 Contributing
- Clone this repository
- Install dependencies using
npm install
- Start development server using
npm run dev
- Make your changes
- Submit a pull request
📄 License
MIT License © 2025 Roberth González