Frontend developers often face a problem related to application architecture. It requires the use of an architecture that can easily scale and provide loose coupling and high cohesion between application modules.
This article discusses the Feature-Sliced Design architecture, as, in my opinion, it is the best among the available options. It also explores the idea of FSD and the problems this architectural methodology solves.
We will compare FSD with classical and modular architectures and examine their pros and cons.
First and foremost, let's distinguish three concepts: layer, slice, and segment.
Layers are top-level directories and the first level of application decomposition. They are limited in number - a maximum of 7 layers - and standardized, although some of them are optional.
Currently, the following layers are distinguished:
Each layer has its own zone of responsibility and is business-oriented. Let's consider each layer separately.
These layers help organize the codebase and promote a modular, maintainable, and scalable architecture.
One of the key features of Feature-Sliced Design is its hierarchical structure. In this structure, entities cannot use functionality from features because features are higher in the hierarchy.
Similarly, features cannot use components from widgets or processes, as the layers above can only utilize the layers below. This is done to maintain a linear flow that is directed only in one direction. The lower a layer is positioned in the hierarchy, the riskier it is to make changes to it since it is likely to be used in more places in the code. For example, the UI kit in the shared layer is used in the features, widgets, and even page layers.
In each of the layers, there are subdirectories - slices—the second level of application decomposition. In slices, the connection is not to abstract things but to specific business entities. The main goal of slices is to group code by its value.
Slice names are not standardized, as they are directly determined by the business area of the project. For example, in a photo gallery, there may be sections like photo, album, and gallery. A social network would require slices like posts, users, and newsfeeds.
Closely related fragments can be structurally grouped in a directory, but they must adhere to the same isolation rules as other slices - there should be no shared access to the code in this directory.
Each slice consists of segments. Segments help to divide the code within a slice based on its purpose. Depending on the team's agreements, segments can change in composition and naming. The following segments are more commonly used:
Each slice and segment has a Public API. The Public API is represented by an index.js or index.ts file, which allows extracting only the necessary functionality from the slice or segment to the outside and isolating unnecessary functionality. The index file serves as an entry point.
Rules for the Public API:
The Public API simplifies working with import and export, so when making changes to the application, there is no need to change imports everywhere in the code.
The higher the layer, the more it is tied to the specific business node and the more business logic it contains. The lower the layer, the more abstractions, reusability, and lack of autonomy in the layer.
One of the tasks of Feature-Sliced Design is to achieve loose coupling and high cohesion. It is important to understand how FSD achieves this result.
In OOP, these problems have long been solved through concepts such as polymorphism, encapsulation, inheritance, and abstraction. These concepts ensure isolation, reusability, and versatility of code, where different results are obtained depending on how a component or functionality is used.
Feature-Sliced Design helps apply these principles in the frontend.
Abstraction and polymorphism are achieved through layers. Since the lower layers are abstract, they can be reused in higher layers, and depending on the conditions, a component or functionality can work differently based on the specified parameters or props.
Encapsulation is achieved through the Public API, which isolates what is not needed from the outside in slices and segments. Access to the inner segments of a slice is restricted, and the Public API is the only way to access functionality and components from a slice or segment.
Inheritance is also achieved through layers, as higher layers can reuse lower layers.
I believe you have come across classic architecture many times. Most authors use it in educational articles and YouTube videos due to its simplicity. There is no specific standard for classical architecture. However, often you can see the following format:
The classic architecture has noticeable drawbacks. The biggest one is that the project becomes difficult to maintain due to implicit connections between components and module clutter. The drawbacks of the classic architecture become more apparent over time. The longer the project evolves, the more the application architecture becomes a tangled mess that is difficult to unravel.
The classic architecture is suitable for small projects without ongoing maintenance or pet projects.
Feature-Sliced Design, thanks to its concepts and standards, prevents the problems of classic architecture.
However, the level of understanding and skills of developers working with FSD should be higher than when working with classic architecture. Usually, developers with less than 2 years of experience have not heard of FSD.
However, when working with Feature-Sliced Design, problems need to be addressed "now" rather than "later." Issues in the code and deviations from the concepts become immediately apparent
Simple modular architecture has several drawbacks:
It seems that in any complex or moderately complex projects, Feature-Sliced Design should be preferred over simple modular architecture. FSD solves many fundamental architectural problems and has few drawbacks.
In terms of simplicity and development speed, a simple modular architecture may have an advantage over FSD. If an MVP is needed or a short-lived project is being developed, a simple modular architecture may be more suitable than FSD. But in any other case, a feature-sliced design looks preferable.
FSD is a young architectural methodology. However, it is already being used by many banking, fintech, B2B, e-commerce companies and others. Here is a link to the GitHub issue with a list of companies: GitHub Issue.
The GitHub repository with the official FSD documentation had more than 1.1k stars at the time of publishing this article. The documentation is actively being expanded, and the FSD development team and community in Telegram and Discord are available 24/7 to help people with architecture-related questions.
The potential of this architecture is highly regarded, and its usage is widely spread among large companies worldwide. With proper adoption, FSD has the potential to become the dominant architectural solution in the field of frontend development.
Feature-Sliced Design is an interesting and valuable discovery that frontend developers should know and be able to use. FSD can provide teams with a flexible, standardized, and scalable architecture and development culture. However, utilizing the positive aspects of the methodology requires knowledge, awareness, and discipline within the team.
FSD stands out among other architectures due to its clear business orientation, entity definition, functional composition, and components composition of the application.
You can also independently explore examples of FSD usage in projects and the official Feature-Sliced Design documentation:
Example. Nike Sneaker and Footwear Store
This post may be long, but I hope you have learned something new. I appreciate that you have finished reading this post.
If you have any thoughts or questions, feel free to leave a comment!
Also published here