Hardware-aware feature flagging system with graceful degradation and progressive enhancement
A comprehensive feature flagging system that detects hardware capabilities and automatically enables/disables features based on device performance. Perfect for applications that need to run smoothly on everything from low-end mobile devices to high-end workstations.
- π Automatic Hardware Detection - Detects CPU, RAM, GPU, network, and storage capabilities
- π Hardware Scoring - Calculates a 0-100 score for intelligent feature gating
- π― Graceful Degradation - Automatically disable heavy features on low-end devices
- π Progressive Enhancement - Enable advanced features on capable hardware
- π€ User Overrides - Allow users to force-enable experimental features
- π§ͺ A/B Testing Support - Built-in support for experimentation
- β‘ Performance Gating - Auto-disable features causing performance issues
- πΎ Persistent Preferences - User preferences saved to localStorage
- βοΈ React Integration - First-class React hooks for easy integration
- π¦ Zero Dependencies - Lightweight, no external dependencies (React is peer/optional)
npm install @superinstance/hardware-aware-flaggingimport {
FeatureFlagRegistry,
FeatureFlagManager,
} from '@superinstance/hardware-aware-flagging';
// Create registry and define features
const registry = new FeatureFlagRegistry([
{
id: 'advanced.animations',
name: 'Advanced Animations',
description: 'Smooth animations and transitions',
category: 'ui',
state: 'enabled',
minHardwareScore: 50,
userOverridable: true,
experimental: false,
tags: ['ui', 'animations'],
dependencies: [],
performanceImpact: 30,
},
{
id: 'ai.local_processing',
name: 'Local AI Processing',
description: 'Run AI models locally',
category: 'ai',
state: 'enabled',
minHardwareScore: 70,
userOverridable: true,
experimental: true,
tags: ['ai', 'local'],
dependencies: [],
performanceImpact: 80,
minRAM: 16,
minCores: 8,
requiresGPU: true,
},
]);
// Create manager
const manager = new FeatureFlagManager(registry, {
debug: true,
persistPreferences: true,
trackMetrics: true,
});
// Initialize
await manager.initialize();
// Check if feature is enabled
if (manager.isEnabled('advanced.animations')) {
// Enable animations
}
// Get hardware capabilities
const hardware = manager.getHardwareCapabilities();
console.log(`Hardware score: ${hardware.score}/100`);
console.log(`Profile: ${hardware.profile}`);import {
FeatureFlagsProvider,
useFeatureFlag,
useHardwareCapabilities,
} from '@superinstance/hardware-aware-flagging/react';
// Wrap your app
function App() {
return (
<FeatureFlagsProvider config={{ debug: true }}>
<MyComponent />
</FeatureFlagsProvider>
);
}
// Use feature flags in components
function MyComponent() {
const hasAnimations = useFeatureFlag('advanced.animations');
const hardware = useHardwareCapabilities();
return (
<div>
<p>Hardware Score: {hardware?.score}/100 ({hardware?.profile})</p>
{hasAnimations ? (
<AnimatedComponent />
) : (
<BasicComponent />
)}
</div>
);
}The system detects hardware capabilities and calculates a score from 0-100:
| Score | Profile | Description |
|---|---|---|
| 0-20 | minimal | Low-end devices, limited features |
| 21-40 | basic | Entry-level devices |
| 41-60 | standard | Mid-range devices |
| 61-80 | advanced | High-end devices |
| 81-100 | premium | Workstations, all features |
Features are evaluated based on:
- User Overrides - Manual enable/disable (highest priority)
- Experimental Status - Requires opt-in for experimental features
- Hardware Score - Minimum score required
- Specific Requirements - RAM, CPU cores, GPU, network
- Dependencies - Required features must be enabled
- Rollout Percentage - Gradual rollout support
enabled- Feature is activedisabled- Feature is inactiveforced- User manually enabled (override)blocked- User manually disabled (override)
interface FeatureFlag {
id: string; // Unique identifier
name: string; // Display name
description: string; // What the feature does
category: FeatureCategory; // ai, ui, knowledge, media, advanced
state: FeatureState; // enabled, disabled, forced, blocked
minHardwareScore: number; // 0-100
userOverridable: boolean; // Can users override?
experimental: boolean; // Is it experimental?
tags: string[]; // For filtering/searching
dependencies: string[]; // Required features
performanceImpact: number; // 0-100
minRAM?: number; // Minimum RAM in GB
minCores?: number; // Minimum CPU cores
requiresGPU?: boolean; // GPU required?
minNetworkSpeed?: number; // Minimum network in Mbps
rolloutPercentage?: number; // Gradual rollout (0-100)
}class FeatureFlagManager {
// Initialize the system
async initialize(): Promise<void>;
// Check if feature is enabled
isEnabled(featureId: string): boolean;
// Get detailed evaluation result
evaluate(featureId: string): EvaluationResult;
// Get all enabled/disabled features
getEnabledFeatures(): string[];
getDisabledFeatures(): string[];
// User controls
enable(featureId: string): void;
disable(featureId: string): void;
reset(featureId: string): void;
// Get hardware capabilities
getHardwareCapabilities(): HardwareCapabilities;
// User preferences
getUserPreferences(): UserPreferences;
updateUserPreferences(updates: Partial<UserPreferences>): void;
// Metrics and monitoring
getMetrics(featureId: string): FeatureMetrics | undefined;
resetMetrics(): void;
// Event listeners
addEventListener(type: FlagEventType, listener: FlagEventListener): void;
removeEventListener(type: FlagEventType, listener: FlagEventListener): void;
// State management
exportState(): string;
importState(state: string): void;
}Check if a feature is enabled.
function StreamingChat() {
const hasStreaming = useFeatureFlag('ai.streaming_responses');
return hasStreaming ? <Streaming /> : <Basic />;
}Get detailed evaluation result with reasoning.
function FeatureStatus({ featureId }: { featureId: string }) {
const result = useFeatureFlagResult(featureId);
if (!result?.enabled) {
return <div>Not available: {result.reason}</div>;
}
return <div>Enabled! Score: {result.hardwareScore}/100</div>;
}Get detected hardware information.
function HardwareInfo() {
const hardware = useHardwareCapabilities();
if (!hardware) return <div>Detecting...</div>;
return (
<div>
<p>Score: {hardware.score}/100</p>
<p>Profile: {hardware.profile}</p>
<p>RAM: {hardware.ram} GB</p>
<p>CPU: {hardware.cores} cores</p>
<p>GPU: {hardware.hasGPU ? 'Yes' : 'No'}</p>
</div>
);
}Control a feature flag (enable/disable/reset).
function FeatureToggle({ featureId }: { featureId: string }) {
const { enabled, enable, disable, reset } = useFeatureFlagControl(featureId);
return (
<div>
<button onClick={enable}>Enable</button>
<button onClick={disable}>Disable</button>
<button onClick={reset}>Auto</button>
<span>Status: {enabled ? 'ON' : 'OFF'}</span>
</div>
);
}function PWA() {
const hasOfflineMode = useFeatureFlag('advanced.offline_mode');
const hasBackgroundSync = useFeatureFlag('advanced.background_sync');
return (
<div>
{hasOfflineMode && <OfflineSupport />}
{hasBackgroundSync && <BackgroundSync />}
</div>
);
}function AIChat() {
const hasLocalModels = useFeatureFlag('ai.local_models');
const hasStreaming = useFeatureFlag('ai.streaming_responses');
const hasMultimodal = useFeatureFlag('ai.multimodal');
return (
<ChatInterface
useLocalModels={hasLocalModels}
enableStreaming={hasStreaming}
supportsMultimodal={hasMultimodal}
/>
);
}function MediaProcessor() {
const hasImageAnalysis = useFeatureFlag('media.image_analysis');
const hasVideoProcessing = useFeatureFlag('media.video_processing');
return (
<div>
{hasImageAnalysis && <ImageAnalyzer />}
{hasVideoProcessing && <VideoProcessor />}
</div>
);
}import { DEFAULT_CONFIG } from '@superinstance/hardware-aware-flagging';
const config = {
...DEFAULT_CONFIG,
debug: true, // Enable debug logging
persistPreferences: true, // Save to localStorage
trackMetrics: true, // Track usage metrics
storageKey: 'myapp-flags', // localStorage key
autoPerformanceGate: true, // Auto-disable on perf issues
performanceThreshold: 1000, // Perf threshold in ms
};import {
FeatureFlagRegistry,
FeatureFlagManager,
resetGlobalRegistry,
} from '@superinstance/hardware-aware-flagging';
describe('Feature Flags', () => {
let registry: FeatureFlagRegistry;
let manager: FeatureFlagManager;
beforeEach(async () => {
resetGlobalRegistry();
registry = new FeatureFlagRegistry([/* features */]);
manager = new FeatureFlagManager(registry, {
persistPreferences: false,
trackMetrics: false,
});
await manager.initialize();
});
test('feature is enabled when hardware score is sufficient', () => {
expect(manager.isEnabled('my.feature')).toBe(true);
});
});See the examples/ directory for complete working examples:
- Basic Usage - Simple feature flagging
- React App - React integration
- A/B Testing - Experimentation
- Performance Gating - Auto-performance gating
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT Β© SuperInstance
Built with inspiration from:
- LaunchDarkly - Feature flagging best practices
- Progressive Enhancement - Web design philosophy
- Graceful Degradation - Fault tolerance pattern
- @superinstance/hardware-capability-profiler - Hardware detection library
- @superinstance/privacy-first-analytics - Privacy-focused analytics
Made with β€οΈ by the SuperInstance team