/documentation

🍰 Structural methodology for frontend projects

Primary LanguageJavaScriptMIT LicenseMIT

Feature-Sliced Design

All Contributors

WIP: The current version of the methodology is under development and some details can be changed

feature-sliced-banner

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

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

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

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

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.

Visual diagram

WIP: The scheme-represents only an approximate division of the project into modules and will be determined definitively closer to the release

visual_schema

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, ...)

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

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 libraries
  • api - the logic of interaction with the API
  • config - the configuration module of the application and its environment

Note: In most cases, it is recommended to place api and config 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

  • 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!

discord          tg          twitter          open-collective          youtube

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Sergey Sova

πŸ“ πŸ“– πŸ’‘ πŸ€” πŸ“† πŸ’¬ πŸš‡ πŸ”¬ πŸ“‹ βœ… πŸ“’ 🚧

Ilya Azin

πŸ“– πŸ’‘ πŸ€” πŸ“† πŸ’¬ πŸ‘€ πŸš‡ πŸ““ 🎨 βœ… πŸ“’ 🚧

Rin 🦊πŸͺπŸ˜ˆ Akaia

πŸ“– πŸ–‹ πŸ€” πŸ’¬ 🌍 πŸ“’ 🚧 πŸ”¬

Alexander Khoroshikh

πŸ“– πŸ€” πŸ’¬ πŸ‘€ πŸ”§ πŸ›‘οΈ πŸ“’ βœ… 🚧

Bear Raytracer

πŸ“– πŸ’‘ πŸ€” πŸ’¬ πŸ‘€ 🌍 🎨 πŸš‡ 🚧

spotsccc

πŸ“– πŸ’‘ πŸ€” πŸ’¬ πŸ‘€ 🚧

Ilya

πŸ“– πŸ€” πŸ“’ 🚧

Viktor Pasynok

πŸ“– πŸ€” πŸ“† πŸ“’

Oleh

πŸ“– πŸ€” βœ…

Niyaz

πŸ’‘ πŸ““

Evgeniy Podgaetskiy

πŸ€”

Viacheslav Zinovev

🎨 πŸ““ πŸ‘€

Alexandr

πŸ€” πŸ““ πŸ‘€

Oleg Isonen

πŸ€” πŸ”¬ πŸ““

Evgeniy

πŸ’» πŸ”Œ πŸ”§

Lev Chelyadinov

πŸ“– πŸ–‹ πŸ€” 🎨

And

πŸš‡ πŸ“– πŸ’»

sarmong

πŸ“– 🌍

Julie Obolenskaya

🌍

Roman Tikhiy

πŸ““ πŸ“–

Igor Kamyshev

πŸ› πŸ“–

Roman

πŸ““ πŸ“–

Sergey Vakhramov

🎨

Mark Omarov

πŸ“–

Π”ΠΌΠΈΡ‚Ρ€ΠΈΠΉ

πŸ’Ό πŸ““

Mihir Shah

🎨

Gleb

πŸ“–

Roma Karvacky

πŸ’‘

Aleksandr Osipov

πŸ““

Maxim

πŸ““

Anton Kosykh

πŸ““

Vladislav Samatov

πŸ““

Oleg Kusov

πŸ“ πŸ““

Andrey Savelev

πŸ““

Nickolay Ilchenko

πŸ““ πŸ“‹

Eugene Ledenev

πŸ”£

Vladislav Romanov

πŸ”£

Ainur

πŸ“–

Elisey Martynov

πŸ’‘

Olga Pasynok

πŸ“‹

Max Kokosha

πŸ’‘

This project follows the all-contributors specification. Contributions of any kind welcome!