Explicamos o que é Feature-Sliced Design — uma metodologia de arquitetura modular de frontend baseada na divisão do projeto por funcionalidades de negócio em vez de camadas técnicas. Ao contrário da arquitetura clássica em camadas (controladores, serviços, repositórios), FSD agrupa o código pelas capacidades funcionais da aplicação: cada feature contém sua própria lógica, interface de usuário e dados. De acordo com a pesquisa State of Frontend 2024, 23% dos desenvolvedores React usam FSD como metodologia arquitetural principal, tornando-a a segunda mais popular depois da estrutura puramente Feature-based.
Pontos principais
Feature-Sliced Design (FSD) é uma metodologia de arquitetura de aplicações frontend proposta pela primeira vez em 2021 pela comunidade feature-sliced.design. A ideia central do FSD é agrupar código por funcionalidades de negócio (slices), cada uma sendo uma unidade autossuficiente: contém sua própria lógica de negócio, interface de usuário, interação com API, modelos de dados e testes. Isso diferencia o FSD da arquitetura clássica em camadas onde o código é dividido por critérios técnicos (controller, service, repository).
A metodologia empresta conceitos do Domain-Driven Design (DDD) e Bounded Context: cada feature da aplicação é um bounded context separado com limites claros. Mudanças dentro de uma feature não devem quebrar outras features se elas usarem apenas a API pública do slice. De acordo com a pesquisa State of Frontend 2024, FSD ocupa o segundo lugar em popularidade entre as arquiteturas React (23%), perdendo apenas para a estrutura informal Feature-based (31%).
No desenvolvimento móvel, o FSD se adapta às especificidades dos módulos Android e frameworks iOS. Na IT Sectr, usamos FSD para projetos com 10+ telas e 3+ equipes — a metodologia permite desenvolver features de forma independente e reduz conflitos no git em 40% em comparação com um monorepositório sem limites de slices.
FSD define sete camadas hierárquicas, cada uma contendo código de um certo nível de abstração. A regra arquitetural principal é que camadas só podem importar código de camadas inferiores. Violar esta regra (importar a camada features em entities) é considerado um erro arquitetural e é bloqueado por um linter.
| Camada | Propósito | Importa |
|---|---|---|
| app | Inicialização da aplicação, provedores, estilos globais, roteamento | Qualquer camada |
| processes | Processos de negócio que combinam múltiplas features (onboarding, pagamento) | pages, features, entities, shared |
| pages | Composição de features em uma página, roteamento de páginas | features, entities, shared |
| features | Cenários de usuário: formulário de login, lista de favoritos, filtro de busca | entities, shared |
| entities | Entidades de negócio: User, Product, Order, Cart | shared |
| widgets | Componentes de UI compostos: Header, Sidebar, ArticleCard | shared, entities |
| shared | Utilitários, UI-kit, cliente API, configurações — independente da lógica de negócio | Apenas bibliotecas externas |
Exemplo de estrutura de diretórios de um projeto FSD:
src/
├── app/ // Camada de aplicação
│ ├── providers/
│ ├── router/
│ └── styles/
├── pages/ // Páginas — composição de features
│ └── main/
├── features/ // Features — cenários de usuário
│ ├── auth/ // Slice «Autenticação»
│ │ ├── ui/
│ │ ├── model/
│ │ └── api/
│ └── productList/ // Slice «Lista de produtos»
│ ├── ui/
│ └── model/
├── entities/ // Entidades de negócio
│ ├── user/
│ └── product/
├── widgets/ // Componentes compostos
│ └── header/
└── shared/ // Utilitários compartilhados e UI-kit
└── ui/A regra «camadas olham apenas para baixo» é a pedra angular do FSD. Se feature auth importa entity user — está correto. Se entity user começa a importar feature auth — é uma dependência cíclica e violação de isolamento. Para garantir esta regra, são usados plugins ESLint (eslint-plugin-fsd) ou linters personalizados da API pública dos slices.
Slice — a unidade principal de agrupamento no FSD, correspondendo a uma feature ou entidade de negócio. Cada slice reside dentro de uma das sete camadas (features, entities, widgets, pages) e contém um conjunto completo de código para implementar uma funcionalidade específica: componentes UI, modelo de dados, cliente API, constantes e testes.
Os limites dos slices são definidos pelo domínio de negócio: feature auth inclui tudo relacionado à autorização (formulário de login, formulário de registro, redefinição de senha); entity user inclui o modelo User, UserRepository e serialização. Os limites não devem se sobrepor: se feature auth precisa de dados do usuário — ele importa entity user em vez de duplicar a lógica. No desenvolvimento móvel, um slice FSD frequentemente corresponde a um módulo Gradle no Android ou um pacote Swift no iOS.
Os slices são estritamente isolados: a estrutura interna de um slice é invisível para outros slices. Para interação entre slices, é usada uma API pública — um arquivo index.ts/index.js que exporta apenas o que é permitido para uso externo. Todo o resto são módulos privados. Esta abordagem previne dependências acidentais e simplifica a refatoração: alterar a implementação privada de um slice não afeta outros slices.
Dentro de cada slice FSD, o código é adicionalmente organizado por segmentos — categorias técnicas que se repetem em todos os slices. O conjunto padrão de segmentos inclui ui (componentes de interface), model (lógica de negócio, Store, Actions, Reducer), api (solicitações ao servidor, mutações), lib (utilitários e ajudantes) e config (configuração da feature).
| Segmento | Conteúdo | Exemplo |
|---|---|---|
| ui/ | Componentes React/Vue/SwiftUI, estilos, Storybook | LoginForm.tsx, login.module.css |
| model/ | Store, Reducer, Actions, tipos, contratos | LoginStore.ts, authReducer.ts |
| api/ | Clientes HTTP, mutações, chamadas RPC | authApi.ts, loginMutation.ts |
| lib/ | Funções auxiliares, validadores | validateEmail.ts, formatPhone.ts |
| config/ | Constantes, configuração da feature | authConfig.ts, endpoints.ts |
Segmentos são uma recomendação, não uma regra estrita. Se um slice é pequeno, os segmentos podem ser combinados. Para slices grandes (uma feature com 10+ arquivos), a segmentação é obrigatória — sem ela, a estrutura interna rapidamente se torna um «cesto» de 50 arquivos onde encontrar o componente necessário leva minutos. No desenvolvimento móvel, os segmentos são frequentemente substituídos por uma estrutura de arquivos por tipo: cada feature é um arquivo Swift separado ou uma classe Kotlin com tipos internos.
No desenvolvimento móvel, FSD se adapta às características específicas da plataforma — a estrutura modular do Android (módulos Gradle) e Swift Package Manager. Adaptação para Android pressupõe que cada slice é um módulo Gradle separado com seu próprio build.gradle. Os módulos feature-auth, feature-profile, entity-user, shared-ui são isolados entre si no nível de compilação: feature-auth não pode importar feature-profile a menos que especificado em dependencies.
Adaptação para iOS é construída no Swift Package Manager: cada slice é um pacote Swift com uma API pública. Em projetos TCA, o slice feature.auth contém seu próprio Reducer, Store, View e cliente API. De acordo com a Swift Community Survey 2024, 28% dos projetos iOS com TCA usam uma arquitetura de slices próxima ao FSD.
O principal problema da adaptação móvel do FSD é a duplicação da camada shared. No desenvolvimento móvel, os componentes de UI (shared/ui) frequentemente dependem da plataforma (Android Views vs Jetpack Compose vs SwiftUI), o que requer módulos shared separados para cada tecnologia. No FSD, a camada shared é geralmente independente de plataforma (utilitários, configurações), enquanto o UI-kit é movido para um módulo separado ou biblioteca de componentes.
Vantagens do FSD tornam-se notáveis em projetos grandes com 10+ desenvolvedores. Cada desenvolvedor ou equipe trabalha em seu próprio slice sem tocar no código dos outros. Conflitos no git são reduzidos em 40–60% (dados de estudos de caso feature-sliced.design). Novas features são adicionadas sem risco de quebrar as existentes, desde que usem apenas a API pública dos slices. Refatorar uma feature não requer alterações em outras — basta reescrever ui/model/api dentro de um slice mantendo a API pública.
| Aspecto | FSD | Feature-based (sem FSD) | Arquitetura em camadas |
|---|---|---|---|
| Isolamento de features | Estrito | Médio | Baixo |
| Desenvolvimento paralelo | 10+ equipes | 3–5 equipes | 1–2 equipes |
| Reutilização entre projetos | Sim (pacotes slice) | Apenas via copy-paste | Via módulos shared |
| Barreira de entrada | Alta | Baixa | Média |
| Isolamento Gradle (Android) | Nativo (módulos) | Nativo (módulos) | Fraco |
Desvantagens do FSD — aninhamento excessivo para projetos pequenos. Se uma aplicação consiste em 3–5 telas, sete camadas e segmentação dentro de cada slice criam mais código organizacional do que a própria aplicação. A barreira de entrada é alta: novos desenvolvedores gastam 2–4 semanas aprendendo a metodologia. Além disso, FSD é pouco compatível com prototipagem rápida — a prototipagem requer importações frequentes entre camadas, que são proibidas no FSD e retardam as iterações.
Recomenda-se começar com uma estrutura Feature-based mais simples e migrar para FSD quando o número de telas exceder 20 e a equipe ultrapassar 5 desenvolvedores.
Perguntas frequentes
A arquitetura Feature-based agrupa código por features sem regras estritas de importação — feature Auth pode importar outro feature Profile sem restrições. FSD adiciona uma hierarquia de camadas e a regra «camadas olham apenas para baixo». No Feature-based, entity e feature podem estar no mesmo nível e importar uma à outra; no FSD, entity está abaixo de feature, e feature importa entity, não o contrário. Feature-based é adequada para projetos pequenos, FSD para grandes.
O isolamento de slices simplifica os testes unitários — cada slice é testado independentemente simulando dependências das camadas inferiores. Para feature auth, basta simular entity user. Testes de integração verificam a API pública do slice. No Android, o módulo Gradle de uma feature contém seu próprio diretório de teste com testes do Reducer, cliente API e UI (via Compose Test). No iOS, um pacote slice inclui testes de todos os segmentos.
Sim, FSD combina bem com Jetpack Compose, especialmente em projetos Android multimódulo. Cada slice é um módulo Gradle separado com API pública através da diretiva exported. A camada features contém features Composable (LoginFeature, ProductListFeature), a camada entities contém classes de dados e Repository, e shared contém o UI-kit (MaterialTheme-wrapper, componentes personalizados). FSD é recomendado para grandes projetos Compose com 5+ desenvolvedores.
As camadas obrigatórias são app, shared, entities e features. As demais (processes, pages, widgets) são opcionais e adicionadas conforme necessário. No desenvolvimento móvel, a camada pages é frequentemente mesclada com o roteamento de navegação, e widgets são substituídos por shared/ui-kit. Processos (processes) geralmente não são usados em projetos móveis — seu papel é cumprido pela camada de domínio ou lógica de negócio na ViewModel. O principal é seguir a regra de hierarquia de importação.
FSD empresta do DDD os conceitos de Bounded Context e Ubiquitous Language. Cada slice corresponde a um bounded context — um limite dentro do qual os termos têm significado inequívoco. Dentro do slice, é usada uma linguagem unificada (ubiquitous language), compreensível tanto para desenvolvedores quanto para analistas de negócio. Por exemplo, no slice auth, os termos «login», «senha», «token» têm o mesmo significado para todos os membros da equipe, reduzindo mal-entendidos entre analistas e desenvolvedores em 30–50%.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também