Quando o deploy é uma dor: por que os desenvolvedores amam feature flags
\n\nImagine: você passou uma semana desenvolvendo uma nova funcionalidade. Cobriu com testes, passou pelo code review, apertou o botão de deploy. E então — bum! — tudo quebra em produção. Usuários furiosos, gerente nervoso, você correndo para reverter a versão. Familiar?
\n\nAgora imagine outro cenário: você ativa a nova funcionalidade apenas para 5% dos usuários. Observa as métricas. Vê que está tudo bem. Aumenta gradualmente a porcentagem para 100%. Sem estresse, sem reversões, apenas confiança tranquila.
\n\nEssa é a mágica dos feature flags (também conhecidos como feature toggles, flags de funcionalidade). Em projetos TypeScript, essa técnica é especialmente boa graças à tipagem estática e ao controle rigoroso de tipos. Hoje vamos entender como implementar feature flags no seu projeto para que você durma tranquilo e as funcionalidades sejam ativadas sem dor.
\n\nO que são feature flags em palavras simples
\n\nFeature flag é um interruptor condicional no código que permite ativar ou desativar uma funcionalidade sem alterar o código e sem um novo deploy. Funciona mais ou menos assim:
\n\nif (featureFlags.isEnabled('new-checkout')) {\n // novo código\n} else {\n // código antigo\n}\n\n\nTudo que é genial é simples, certo? Mas por trás dessa simplicidade está uma ferramenta poderosa usada por Google, Netflix, Facebook e outros gigantes. Eles não fazem deploy de cada detalhe — eles gerenciam o comportamento da aplicação através de um painel de controle centralizado.
\n\nQuando feature flags são realmente necessárias
\n\n- \n
- Canary release — lançamento de uma nova funcionalidade para uma pequena parte dos usuários \n
- Dark launch — teste oculto, onde a funcionalidade existe mas os usuários não a veem \n
- Teste A/B — comparação de duas versões de uma funcionalidade \n
- Kill switch — desativação de emergência de código problemático sem deploy \n
- Teste de permissão — teste em usuários internos ou por funções \n
Em projetos TypeScript, os feature flags ganham um charme especial: o compilador verifica se você está usando as flags corretamente, não confunde tipos e não esquece de tratar todos os estados.
\n\nArquitetura do sistema de feature flags
\n\nAntes de escrever código, vamos entender do que consiste um sistema bem projetado de gerenciamento de funcionalidades.
\n\nComponentes básicos
\n\n- \n
- Armazenamento de flags — onde os valores ficam (JSON, banco de dados, serviço externo) \n
- Provedor — módulo que carrega e armazena em cache as flags \n
- Parte cliente — código que verifica o estado das flags \n
- Painel de controle — interface para alterar as flags em tempo real \n
Implementação mais simples em TypeScript
\n\nVamos começar com o exemplo mais básico. Criaremos um tipo para as flags e um serviço simples:
\n\n// types/feature-flags.ts\nexport type FeatureFlag = \n | 'new-checkout'\n | 'dark-mode'\n | 'recommendations-v2'\n | 'beta-chat';\n\nexport interface FeatureFlagConfig {\n flag: FeatureFlag;\n enabled: boolean;\n rolloutPercentage?: number;\n userIds?: string[];\n}\n\n\nAgora escrevemos o serviço em si:
\n\n// services/feature-flag.service.ts\nexport class FeatureFlagService {\n private flags: Map<FeatureFlag, FeatureFlagConfig> = new Map();\n\n constructor(initialFlags: FeatureFlagConfig[]) {\n initialFlags.forEach(flag => {\n this.flags.set(flag.flag, flag);\n });\n }\n\n isEnabled(flag: FeatureFlag, userId?: string): boolean {\n const config = this.flags.get(flag);\n if (!config) return false;\n\n if (!config.enabled) return false;\n\n // Verificação por usuários específicos\n if (config.userIds && userId) {\n return config.userIds.includes(userId);\n }\n\n // Rollout por porcentagem