Streamlining Feature Management in HazelJS with @hazeljs/feature-toggle
These articles are AI-generated summaries. Please check the original sources for full details.
Feature Flags with One Decorator: Introducing @hazeljs/feature-toggle
Muhammad Arslan has introduced @hazeljs/feature-toggle, a lightweight utility designed for the HazelJS ecosystem. The package uses a single decorator to reject unauthorized requests with a 403 status when a feature flag is disabled.
Why This Matters
Developers often struggle with messy conditional logic scattered across controllers and services, leading to high maintenance debt and inconsistent application states. By abstracting these checks into a decorator-first architecture, @hazeljs/feature-toggle replaces manual route guarding with a centralized, in-memory store that can be seeded via environment variables for consistent behavior across deployment stages.
Key Insights
- Route-level control via @FeatureToggle automatically composes with HazelJS guards to block disabled endpoints without manual wiring (2026).
- Environment variable integration using the envPrefix option allows variables like FEATURE_NEW_UI to be mapped to camelCase keys automatically.
- Programmatic branching via FeatureToggleService.isEnabled() provides a clean API for non-route logic within services and pipelines.
- The package utilizes an in-memory store by default, avoiding the latency and dependency overhead of external SaaS providers on day one.
- A guard-per-flag design pattern caches guard classes per feature name to optimize performance during the HazelJS request pipeline.
Working Examples
Protecting specific routes using the @FeatureToggle decorator.
@Controller('checkout')
export class CheckoutController {
@Get('new')
@FeatureToggle('newCheckout')
getNewCheckout() {
return { flow: 'new' };
}
@Get('legacy')
getLegacyCheckout() {
return { flow: 'legacy' };
}
}
Registering the module with initial flags and environment variable prefixing.
FeatureToggleModule.forRoot({
initialFlags: { newCheckout: true },
envPrefix: 'FEATURE_',
})
Injecting FeatureToggleService for programmatic branching in business logic.
@Service()
export class OrderService {
constructor(private readonly featureToggle: FeatureToggleService) {}
createOrder(data: OrderData) {
if (this.featureToggle.isEnabled('newCheckout')) {
return this.createWithNewFlow(data);
}
return this.createWithLegacyFlow(data);
}
}
Practical Applications
- Beta Endpoint Management: Apply @FeatureToggle to a controller class to restrict entire API modules to staging environments. Pitfall: Hardcoding flag names in multiple files can lead to orphaned code if flags are not decommissioned after rollout.
- Safe System Rollouts: Use FeatureToggleService to branch between legacy and new logic flows within a service. Pitfall: Relying on in-memory storage without environment variable seeding causes flag state loss during process restarts.
References:
Continue reading
Next article
Building Your First Solana dApp with Rust and Anchor
Related Content
AI-Assisted Coding's Last Mile: The Signup Form and the Secrets Problem
Developer Bento Maker identifies the signup form as the final bottleneck in AI-assisted coding, building a driver that solves anti-bot gating and secret management.
How to Build an AI-Driven Property Management Email Agent Without Shared Inbox Chaos
Build a property-management email agent that auto-prioritizes tenant requests with an LLM and routes vendors via server-side rules, eliminating the bottleneck of manual triage in a shared human inbox.
React-Native Downloader: Native HTTP Client for Multi-Gigabyte AI Model Files
A new open-source React Native package provides native direct-to-file downloads with resumable support, targeting large AI model files that can be multiple gigabytes.