Feature-Sliced Design
WIP:
The current version of the methodology is under development and some details can be changed
Feature-Sliced Design (FSD) is an architectural design methodology for frontend applications. It aims to divide an application according to business logic and scopes of responsibility
- Provides explicitness, controllability and adaptability of architecture
- Based on time-tested design practices and concepts
SOLID
,GRASP
,DDD
,Separation of Concerns
,Vertical Slices
,Public API
,Isolation
- Suggests dividing the project according to business units
Note: The methodology is not tied to a specific tech stack and is applicable to any frontend projects in general.
But the current version is based on and provides examples for
JavaScript
+React
stack.
Motivation
Usually, approaches to building the frontend architecture from project to project are re-invented from scratch, thereby adding "project knowledge"
Despite the fact that the specifics of frontend projects do not differ so much
At the same time, incorrectly made decisions often lead to problems of scalability of the project and the team.
And therefore, instead of inventing and documenting it every time, it is better to summarize the experience and form a working, battle-tested and documented methodology for designing the frontend architecture.
Yes, there are many practices and patterns (SOLID
, GRASP
, DDD
, ...)
But for the frontend it is highly difficult to find well-established and specific approaches
Overview
The methodology is designed to simplify and standardize the decomposition of logic for large and long-lived projects.
To do this, it introduces a number of concepts and abstractions, on which the architecture can be based from project to project - from here we get a number of advantages
Note: Module - the structural unit of the project (file / directory)
Explicit business logic
Modules are distributed according to scope of influence, business responsibility and technical purpose
Thanks to this, the architecture is standardized and becomes easier to read
Adaptation to new conditions
Each component of the architecture has its own purpose and does not affect the others
Thanks to this it is possible to independently modify the functionality of the application to meet new requirements without unforeseen consequences
Technical debt and refactoring
Each module is independent and self-sufficient
Thanks to this you can rewrite it from scratch without unexpected side effects
Scaling the project and the team
The increase in functionality leads to significantly less complexity of the project, since all the logic is distributed deterministically and in isolation
Thanks to this it is easy to add and onboard new people to the team, as well as expand the functionality of the project
Controlled reuse of logic
Each module has its own limitations and recommendations for reuse according to its layer
Thanks to this, a balance is maintained between compliance with the DRY
principle and the ability to customize the module logic without overhead overrides
Concepts
Public API
Each module must have a declaration of its public API at the top level
- To connect to other modules, without the need to refer to the internal structure of this module
- To isolate the implementation details from the consumer modules
- Also, the Public API should protect the module interface after refactoring - in order to avoid unforeseen consequences
Isolation
The module should not depend directly on other modules of the same layer or overlying layers
- The concept is also known as
Low Coupling & High Cohesion
- to prevent implicit connections / side effects during development and refactoring
Needs driven
Orientation to the needs of the business and the user
- Also includes splitting the structure by business domains (so-called "slices")
Abstractions
For architecture design the methodology suggests operating with familiar abstractions, but in a more consistent and consistent order.
Layers
The first level of abstraction is according to the scope of influence
app
- application initialization (init, styles, providers, ...)processes
- application business processes that manage pages (payment, auth, ...)pages
- application pages (user-page, ...)features
- parts of the application functionality (auth-by-oauth, ...)entities
- business entities (viewer, order, ...)shared
- reused infrastructure code (UIKit, libs, API, ...)
Slices
The second level of abstraction is according to the business domain
The rules by which the code is divided into slices depend on the specific project and its business rules and are not determined by the methodology
Segments
The third level of abstraction is according to the purpose in the implementation
ui
- UI-representation of the module (components, widgets, canvas, ...)model
- business logic of the module (store, effects/actions, hooks/contracts, ...)lib
- auxiliary librariesapi
- the logic of interaction with the APIconfig
- the configuration module of the application and its environment
Note: In most cases, it is recommended to place
api
andconfig
only in the shared layer
Structure
βββ src/
βββ app/ # Layer: Application
| #
βββ processes/ # Layer: Processes (optional)
| βββ {some-process}/ # Slice: (e.g. CartPayment process)
| | βββ lib/ # Segment: Infrastructure-logic (helpers/utils)
| | βββ model/ # Segment: Business Logic
| ... #
| #
βββ pages/ # Layer: Pages
| βββ {some-page}/ # Slice: (e.g. ProfilePage page)
| | βββ lib/ # Segment: Infrastructure-logic (helpers/utils)
| | βββ model/ # Segment: Business Logic
| | βββ ui/ # Segment: UI logic
| ... #
| #
βββ widgets/ # Layer: Widgets
| βββ {some-widget}/ # Slice: (e.g. Header widget)
| | βββ lib/ # Segment: Infrastructure-logic (helpers/utils)
| | βββ model/ # Segment: Business Logic
| | βββ ui/ # Segment: UI logic
βββ features/ # Layer: Features
| βββ {some-feature}/ # Slice: (e.g. AuthByPhone feature)
| | βββ lib/ # Segment: Infrastructure-logic (helpers/utils)
| | βββ model/ # Segment: Business Logic
| | βββ ui/ # Segment: UI logic
| ... #
| #
βββ entities/ # Layer: Business entities
| βββ {some-entity}/ # Slice: (e.g. entity User)
| | βββ lib/ # Segment: Infrastructure-logic (helpers/utils)
| | βββ model/ # Segment: Business Logic
| | βββ ui/ # Segment: UI logic
| ... #
| #
βββ shared/ # Layer: Reused resources
| βββ api/ # Segment: Logic of API requests
| βββ config/ # Segment: Application configuration
| βββ lib/ # Segment: Infrastructure-application logic
| βββ ui/ # Segment: UIKit of the application
| ... #
| #
βββ index.tsx/ #
Further reading
- Methodology documentation
Get-Started, Concepts, Guides, Reference, About
- Migration from feature-slices@v1
- Other materials
- Another versions of the methodology: feature-slices, feature-driven
- React SPB Meetup Report #1 - Feature Slices
- Feature Driven Architecture - Oleg Isonen
- A feature based approach to React development
- Why React developers should modularize their applications?
- How to Organize Your React + Redux Codebase
- The Humanizing Work Guide to Splitting User Stories (aka "Vetical Slices")
- Discussions on the methodology
- Real application examples, questions, problems, ideas of the methodology are discussed and analyzed here
- All this together affects the specification, the toolkit and, in general, the further vision and development of the methodology
- That is, everything that is not yet in the specification/toolkit is somehow discussed in github-discussions
- How can I help?
- β Rate us on GitHub
- π« Any assistance is important - from feedback to participation in the development of the methodology!
Contributors β¨
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!