When building software, releasing new features quickly without breaking anything can be tricky. Feature flags make this easier. After reading about Vercel’s Feature Flag SDK, I thought it would be helpful to study more about feature flags and explain what they are, how they work, and how you can build one on your own.
What are Feature Flags?
Feature flags (also called feature toggles) allow developers to turn features on or off without needing to change the code or redeploy the application. This means you can:
- Release features gradually: Let only some users see the new feature and slowly roll it out to everyone.
- Test new features in production: You can enable the feature for yourself or a small group of testers without making it available to all users.
- Quickly roll back a feature: If a new feature causes issues, you can disable it without redeploying.
With feature flags, you control when users can access features, separate from when the code is deployed.
Why Use Feature Flags?
-
Continuous Delivery
Feature flags help teams release code more frequently. You can merge unfinished work into the main codebase, hide it behind a flag, and deploy it without affecting users.
-
A/B Testing
You can test two versions of a feature with different user groups to see which performs better. This helps improve the user experience based on real data.
-
Controlled Rollouts
You can release a feature to a small group of users, monitor its performance, and then release it to everyone else.
-
Quick Rollbacks
If something goes wrong, turning off the feature flag is much faster than reverting code changes, helping to keep the app stable.
Using Feature Flags in Next.js with Vercel's Flags SDK
flags.ts (Server-side)
import { unstable_flag as flag } from "@vercel/flags/next";
export const showBanner = flag({
key: "banner",
decide: () => false,
});
The decide
function determines the flag’s value, which can be provided from various sources such as:
- Environment variables
- Other feature flag providers
- Vercel's Edge Config (data config store)
- Databases, etc.
app/page.tsx
import { showBanner } from "../flags";
export default async function Page() {
const banner = await showBanner();
return (
<div>
{banner ? <Banner /> : null}
{/* other components */}
</div>
);
}
Since the flags are functions, we can easily change the implementation without modifying anything on the calling side. This flexibility allows your application to adapt to new requirements without needing to alter the core structure of the flag logic.
How to Build Your Own Feature Flag System
Let’s build a simple feature flag system that you can improve over time.
Step 1: Create a Custom Hook for Retrieving Feature Flags
This step involves creating a custom hook that will allow you to retrieve feature flags dynamically. You can easily reuse this hook in any part of your React application to check if a feature is enabled or disabled.
import { useState, useEffect } from 'react';
export const useFeatureFlag = (key: string): boolean => {
const [isEnabled, setIsEnabled] = useState<boolean>(false);
useEffect(() => {
const fetchFeatureFlag = async () => {
try {
const response = await fetch(`http://localhost:3001/api/feature-flags/${key}`);
if (response.ok) {
const data = await response.json();
setIsEnabled(data.is_enabled);
}
} catch (error) {
console.error('Failed to fetch feature flag:', error);
}
};
fetchFeatureFlag();
}, [key]);
return isEnabled;
};
Step 2: React Component
Next, create a component that uses the custom hook to render different features based on whether the flag is enabled or disabled. This will allow your application to seamlessly switch between old and new functionality without any disruption to the user experience.
import React from 'react';
import { useFeatureFlag } from './useFeatureFlag';
const FeatureFlaggedComponent: React.FC = () => {
const isNewFeatureEnabled = useFeatureFlag('new-feature');
return (
<div>
<h1>Feature Flag Example</h1>
{isNewFeatureEnabled ? (
<div>
<h2>New Feature</h2>
<p>This is the new feature enabled by the feature flag.</p>
</div>
) : (
<div>
<h2>Old Feature</h2>
<p>This is the old feature displayed when the new feature is disabled.</p>
</div>
)}
</div>
);
};
export default FeatureFlaggedComponent;
Other Feature Flag Solutions in the Market
Building your own feature flag system is useful for small projects, but if you're working with larger teams or need more advanced control, several tools offer feature flagging as a service:
-
Vercel offers feature flags integrated with their platform, allowing real-time control over which users see which features.
-
LaunchDarkly is a popular tool for managing feature flags at scale. It supports complex rollouts, targeting users based on attributes like location or behavior.
-
Optimizely focuses on experimentation and A/B testing, using feature flags to test different features and improve user experience.
-
Split.io allows teams to divide traffic between different feature versions and track performance metrics in real-time.
Hypertune is a newer player in the feature flagging space, focusing on high-performance experimentation and feature toggling. It enables teams to run complex experiments with minimal latency, ensuring real-time performance insights. Hypertune's unique approach integrates feature flags with machine learning models, allowing for more intelligent decision-making in terms of feature rollouts and user targeting.
Conclusion
Feature flags are an excellent way to release features safely, test in production, and make quick changes without redeploying code. You can build a simple feature flag system using JavaScript or use more advanced tools like Vercel, LaunchDarkly, or Optimizely for larger projects.
Using feature flags will make your development process more flexible and efficient, allowing you to deliver new features faster and more confidently.
Thanks for reading, and please feel free to share your comments!
Top comments (0)