We leggen uit wat Feature-Sliced Design is — een methodologie voor modulaire frontend-architectuur, gebaseerd op het verdelen van een project op basis van bedrijfsfeatures in plaats van technische lagen. In tegenstelling tot klassieke gelaagde architectuur (controllers, services, repositories), groepeert FSD code op basis van functionele mogelijkheden van de applicatie: elke feature bevat zijn eigen logica, UI en gegevens. Volgens de State of Frontend 2024-enquete gebruikt 23% van de React-ontwikkelaars FSD als primaire architectuurmethodologie, waarmee het de tweede meest populaire is na pure Feature-based structuur.
Belangrijkste punten
Feature-Sliced Design (FSD) — een methodologie voor frontend-applicatiearchitectuur, voor het eerst voorgesteld in 2021 door de community feature-sliced.design. Het hoofdidee van FSD is het groeperen van code op basis van bedrijfsfeatures (slices), die elk een zelfvoorzienende eenheid zijn: ze bevatten hun eigen bedrijfslogica, gebruikersinterface, API-werking, gegevensmodellen en tests. Dit onderscheidt FSD van klassieke gelaagde architectuur, waar code is verdeeld op technisch criterium (controller, service, repository).
De methodologie leent concepten van Domain-Driven Design (DDD) en Bounded Context: elke applicatiefeature is een aparte bounded context met duidelijke grenzen. Wijzigingen binnen een feature mogen andere features niet breken als ze alleen de publieke API van de slice gebruiken. Volgens de State of Frontend 2024-enquete staat FSD op de tweede plaats qua populariteit onder React-architecturen (23%), alleen achter de informele Feature-based structuur (31%).
In mobiele ontwikkeling wordt FSD aangepast aan de specifieke kenmerken van Android-modules en iOS-frameworks. Bij IT Sectr gebruiken we FSD voor projecten met 10+ schermen en 3+ teams — de methodologie maakt onafhankelijke ontwikkeling van features mogelijk en vermindert het aantal git-conflicten met 40% in vergelijking met een monorepository zonder slice-grenzen.
FSD definieert zeven hierarchische lagen, die elk code van een bepaald abstractieniveau bevatten. De hoofdregel van de architectuur — lagen kunnen alleen code van lager gelegen lagen importeren. Overtreding van deze regel (import van de features-laag in entities) wordt beschouwd als een architectuurfout en wordt geblokkeerd door de linter.
| Laag | Doel | Importeert |
|---|---|---|
| app | Applicatie-initialisatie, providers, globale stijlen, routing | Elke laag |
| processes | Bedrijfsprocessen die meerdere features combineren (onboarding, betaling) | pages, features, entities, shared |
| pages | Compositie van features op een pagina, paginarouting | features, entities, shared |
| features | Gebruikersscenario's: inlogformulier, favorietenlijst, zoekfilter | entities, shared |
| entities | Bedrijfsentiteiten: User, Product, Order, Cart | shared |
| widgets | Compositie-UI-componenten: Header, Sidebar, ArticleCard | shared, entities |
| shared | Hulpprogramma's, UI-kit, API-client, configuratie — onafhankelijk van bedrijfslogica | Alleen externe bibliotheken |
Voorbeeld van een directorystructuur van een FSD-project:
src/
├── app/ // Applicatielaag
│ ├── providers/
│ ├── router/
│ └── styles/
├── pages/ // Pagina's — compositie van features
│ └── main/
├── features/ // Features — gebruikersscenario's
│ ├── auth/ // Slice authenticatie
│ │ ├── ui/
│ │ ├── model/
│ │ └── api/
│ └── productList/ // Slice productlijst
│ ├── ui/
│ └── model/
├── entities/ // Bedrijfsentiteiten
│ ├── user/
│ └── product/
├── widgets/ // Compositiecomponenten
│ └── header/
└── shared/ // Algemene hulpprogramma's en UI-kit
└── ui/De regel lagen kijken alleen naar beneden — de hoeksteen van FSD. Als feature auth de entiteit user importeert — is dat correct. Als entiteit user feature auth begint te importeren — is dat een cyclische afhankelijkheid en schending van isolatie. Om naleving van de regel te waarborgen, worden ESLint-plugins (eslint-plugin-fsd) of eigen linters van de publieke API van slices gebruikt.
Een slice — de primaire groeperingseenheid in FSD, overeenkomend met een bedrijfsfeature of entiteit. Elke slice bevindt zich in een van de zeven lagen (features, entities, widgets, pages) en bevat de volledige code-set voor het implementeren van specifieke functionaliteit: UI-componenten, gegevensmodel, API-client, constanten en tests.
De grenzen van slices worden bepaald door het bedrijfsdomein: feature auth omvat alles wat met authenticatie te maken heeft (inlogformulier, registratieformulier, wachtwoord resetten); entiteit user omvat het User-model, UserRepository en serialisatie. Grenzen mogen elkaar niet overlappen: als feature auth gebruikersgegevens nodig heeft — importeert het entiteit user, in plaats van logica te kopieren. In mobiele ontwikkeling komt een FSD-slice vaak overeen met een Gradle-module in Android of een Swift-pakket in iOS.
Slices zijn strikt geisoleerd: de interne structuur van een slice is onzichtbaar voor andere slices. Voor interactie tussen slices wordt de publieke API gebruikt — het bestand index.ts/index.js dat alleen exporteert wat van buitenaf mag worden gebruikt. Al het andere zijn prive-modules. Deze aanpak voorkomt toevallige afhankelijkheden en vereenvoudigt refactoring: het wijzigen van de prive-implementatie van een slice heeft geen invloed op andere slices.
Binnen elke FSD-slice wordt code verder georganiseerd in segmenten — technische categorieen die in alle slices worden herhaald. De standaard set segmenten omvat ui (interfacecomponenten), model (bedrijfslogica, Store, Actions, Reducer), api (serververzoeken, mutaties), lib (hulpprogramma's en helpers) en config (feature-configuratie).
| Segment | Inhoud | Voorbeeld |
|---|---|---|
| ui/ | React/Vue/SwiftUI-componenten, stijlen, Storybook | LoginForm.tsx, login.module.css |
| model/ | Store, Reducer, Actions, types, contracten | LoginStore.ts, authReducer.ts |
| api/ | HTTP-clients, mutaties, RPC-aanroepen | authApi.ts, loginMutation.ts |
| lib/ | Hulpfuncties, validators | validateEmail.ts, formatPhone.ts |
| config/ | Constanten, feature-configuratie | authConfig.ts, endpoints.ts |
Segmenten zijn een aanbeveling, geen strikte regel. Als een slice klein is, kunnen segmenten worden gecombineerd. Voor grote slices (feature met 10+ bestanden) is segmentatie verplicht — zonder verandert de interne structuur snel in een mand met 50 bestanden, waar het vinden van de juiste component minuten duurt. In mobiele ontwikkeling worden segmenten vaak vervangen door een bestandsstructuur op type: elke feature is een apart Swift-bestand of Kotlin-klasse met interne typen.
In mobiele ontwikkeling wordt FSD aangepast aan platformspecifieke kenmerken — de modulaire structuur van Android (Gradle-modules) en Swift Package Manager. Android-aanpassing gaat ervan uit dat elke slice een aparte Gradle-module is met zijn eigen build.gradle. De modules feature-auth, feature-profile, entity-user, shared-ui zijn van elkaar geisoleerd op build-niveau: feature-auth kan feature-profile niet importeren tenzij dit in dependencies is gespecificeerd.
iOS-aanpassing is gebaseerd op Swift Package Manager: elke slice is een Swift-pakket met een publieke API. In TCA-projecten bevat slice feature.auth zijn eigen Reducer, Store, View en API-client. Volgens de Swift Community Survey 2024 gebruikt 28% van de iOS-projecten met TCA een slice-architectuur die dicht bij FSD ligt.
Het belangrijkste probleem van mobiele FSD-aanpassing — duplicatie van de shared-laag. In mobiele ontwikkeling zijn UI-componenten (shared/ui) vaak platformafhankelijk (Android Views vs Jetpack Compose vs SwiftUI), wat aparte shared-modules voor elke technologie vereist. In FSD is de shared-laag meestal platformonafhankelijk (hulpprogramma's, configuraties), en wordt de UI-kit ondergebracht in een aparte module of componentenbibliotheek.
Voordelen van FSD worden zichtbaar in grote projecten met 10+ ontwikkelaars. Elke ontwikkelaar of team werkt aan zijn eigen slice, zonder andermans code aan te raken. Git-conflicten verminderen met 40–60% (gegevens uit feature-sliced.design case studies). Nieuwe features worden toegevoegd zonder het risico bestaande te breken, als ze alleen de publieke API van slices gebruiken. Refactoring van een feature vereist geen wijziging van andere — het volstaat om ui/model/api binnen een slice te herschrijven met behoud van de publieke API.
| Aspect | FSD | Feature-based (zonder FSD) | Gelaagde architectuur |
|---|---|---|---|
| Isolatie van features | Strikt | Gemiddeld | Laag |
| Parallelle ontwikkeling | 10+ teams | 3–5 teams | 1–2 teams |
| Hergebruik tussen projecten | Ja (slice-pakketten) | Alleen via copy-paste | Via shared-modules |
| Toegangsdrempel | Hoog | Laag | Gemiddeld |
| Gradle-isolatie (Android) | Native (modules) | Native (modules) | Zwak |
Nadelen van FSD — overmatige nesting voor kleine projecten. Als een applicatie uit 3–5 schermen bestaat, creeren zeven lagen en segmentatie binnen elke slice meer organisatiecode dan de applicatie zelf. De toegangsdrempel is hoog: nieuwe ontwikkelaars besteden 2–4 weken aan het leren van de methodologie. Ook is FSD slecht compatibel met rapid prototyping — een prototype vereist frequente cross-layer imports die in FSD verboden zijn en iteraties vertragen.
Het wordt aanbevolen om te beginnen met een eenvoudigere Feature-based structuur en te migreren naar FSD wanneer het aantal schermen 20 overschrijdt en het team 5 ontwikkelaars.
Veelgestelde vragen
Feature-based architectuur groepeert code op features zonder strikte importregels — feature Auth kan een andere feature Profile importeren zonder beperkingen. FSD voegt een hierarchie van lagen en de regel lagen kijken alleen naar beneden toe. In Feature-based kunnen entiteit en feature op hetzelfde niveau staan en elkaar importeren; in FSD ligt entiteit onder feature, en feature importeert entiteit, maar niet andersom. Feature-based is geschikt voor kleine projecten, FSD voor grote.
Isolatie van slices vereenvoudigt modulair testen — elke slice wordt onafhankelijk getest door het vervangen van afhankelijkheden van lager gelegen lagen. Voor feature auth is het voldoende om entiteit user te mocken. Integratietests controleren de publieke API van de slice. In een Android Gradle-module bevat de feature een eigen testmap met tests voor Reducer, API-client en UI (via Compose Test). In iOS bevat het slice-pakket tests voor alle segmenten.
Ja, FSD combineert goed met Jetpack Compose, vooral in multi-module Android-projecten. Elke slice is een aparte Gradle-module met publieke API via de exported-richtlijn. De laag features bevat Composable-features (LoginFeature, ProductListFeature), de laag entities bevat dataklassen en Repository, shared — UI-kit (MaterialTheme-wrapper, aangepaste componenten). FSD wordt aanbevolen voor grote Compose-projecten met 5+ ontwikkelaars.
Verplichte lagen zijn app, shared, entities en features. De overige (processes, pages, widgets) zijn optioneel en worden toegevoegd indien nodig. In mobiele ontwikkeling wordt de laag pages vaak gecombineerd met navigatie-routing, en worden widgets vervangen door shared/ui-kit. Processen (processes) worden meestal niet gebruikt in mobiele projecten — hun rol wordt vervuld door de domain-laag of bedrijfslogica in ViewModel. Het belangrijkste is het naleven van de import-hierarchie.
FSD leent van DDD het concept van Bounded Context en Ubiquitous Language. Elke slice komt overeen met een bounded context — een grens waarbinnen termen een ondubbelzinnige betekenis hebben. Binnen een slice wordt een uniforme taal (ubiquitous language) gebruikt, begrijpelijk voor zowel ontwikkelaars als bedrijfsanalisten. Bijvoorbeeld, in de slice auth hebben de termen login, wachtwoord, token dezelfde betekenis voor alle teamleden, wat het aantal misverstanden tussen analisten en ontwikkelaars met 30–50% vermindert.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook