Feature-Sliced Design: The Best Frontend Architecture
Tags: webdev, frontend, architecture, react
Published: 2023-07-18 15:25:19

## Introduction
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, Slices, Segments](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vscch6q7ej44oxkwensa.jpg)

## Layers
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:

![Layers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8h9nfpy3o2arlnqx305.png)
Each layer has its own zone of responsibility and is business-oriented.
Let's consider each layer separately.

- app: This is where the application logic is initialized. Providers, routers, global styles, global type declarations, etc. are defined here. It serves as the entry point of the application.
- processes: This layer handles processes that span across multiple pages, such as multi-step registration. This layer is considered deprecated but can still be occasionally encountered. It is an optional layer.
- pages: This layer includes the application's pages.
- widgets: These are standalone UI components used on pages.
- features: This layer deals with user scenarios and functionality that carries business value. For example, likes, writing reviews, rating products, etc. It is an optional layer.
- entities: This layer represents business entities. These entities can include users, reviews, comments, etc. It is an optional layer.
- shared: This layer contains reusable components and utilities that are not tied to specific business logic. It includes UI kit, axios configuration, application configuration, and helpers that are not bound to business logic, etc.

These layers help organize the codebase and promote modular, maintainable, and scalable architecture.

![Github Layers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imjod1r4jmgwrnkxysm8.jpg)

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.
![Layers Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0icvw9lyxhc8vy87svif.png)
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 pages layers.

## Slices
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, gallery. A social network would require slices like post, user, newsfeed.

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.

![Slices](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0514x3zt2kl9tpfrdzu4.png)

## Segments
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:

- api - necessary server requests
- UI - UI components of the slice
- model - Business logic, i.e., interaction with the state. For example, actions and selectors
- lib - auxiliary functionality used within the slice
- config - necessary configuration of the slice, but the config segment is rarely encountered
- consts - necessary constants

## Public API
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:

- Application slices and segments use only the functionality and components of the slice that are defined in the Public API index file.
- The internal part of the slice or segment that is not defined in the Public API is considered isolated and only open for access within the slice or segment itself.

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.

![Public API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6eo1c600ju1ca5t2gjhs.png)

## Deeper into architecture

### Abstraction and business logic
The higher the layer, the more it is tied to the specific buissnes node and the more business logic it contains. The lower the layer, the more abstractions, reusability, and lack of autonomy in the layer.

![Abstraction of Layers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2dxngoac33r132w8sl0s.png)

### How does FSD solve the problem?
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.

### Comparison with the classic architecture
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:

![Classic Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fg5ayflluz5jr5yrqwl4.png)
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 the classic architecture. However, the level of understanding and skills of developers working with FSD should be higher than when working with the 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

### Comparison with simple modular architecture
Simple modular architecture has several drawbacks:

- Sometimes it is unclear where to put functionality into modules or components.
- Difficulties in using modules within another module.
- Issues with storing business entities.
- Implicit dependencies in global functions, leading to a tangled structure.

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, simple modular architecture may have an advantage over FSD. If an MVP is needed or a short-lived project is being developed, simple modular architecture may be suitable than FSD. But in any other case Feature-Sliced Design looks preferable.

### Conflicts between Next.js and FSD
Recently, there has been a growing trend of using Next.js together with Feature-Sliced Design. Next.js works well with FSD, but there are conflicts in two areas: file routing in pages and the absence of an app.

#### Pages
For Next.js, pages is a directory with file routing, where each component represents a route. For FSD, pages is a layer with a flat list of pages. This creates a conflict: how to combine Next.js pages with FSD pages.

When using Next.js and FSD together, you can store Next.js pages in the root of the application: `[root]/pages/`, and store FSD pages in a src folder: `[root]/src/pages/`.

Another solution to resolve the conflict is to maintain two directories: a renamed flat list of pages from FSD, such as pages-flat, and nested routes in Next.js - pages. The page code is stored in pages-flat and exported to pages.

You can use either method, but I prefer the first one.

#### App
Next.js handles all the basic functionality of the app layer. However, if you still need to run something for the entire application independent of the page, you can create a layout for the entire application using the Layout Pattern.

Next.js documentation about Layout Pattern: [Routing: Pages and Layouts | Next.js](https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts#layout-pattern)

### The Potential of Feature-Sliced Design
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](https://github.com/feature-sliced/documentation/issues/131).

The Github repository with the official FSD documentation has 858 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.

## Advantages and disadvantages of architecture

### Advantages

- Architecture components can be easily replaced, added, or removed
- Standardization of architecture
- Scalability
- Methodology is independent of the development stack
- Controlled and explicit connections between modules without unexpected side effects
- Business-oriented architectural methodology

### Disadvantages

- Higher entry barrier compared to many other architectural solutions
- Requires awareness, team culture, and adherence to concepts
- Challenges and issues need to be addressed immediately, rather than later. Code problems and deviations from concepts are immediately visible. However, this can also be seen as an advantage

## Conclusion
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 and components composition of the application.

You can also independently explore examples of FSD usage in projects and the official Feature-Sliced Design documentation:

[Documentation](https://feature-sliced.design/)
[Example. Github Client](https://github.com/ani-team/github-client)
[Example. Nike Sneaker and Footwear Store](https://github.com/noveogroup-amorgunov/nukeapp)
[Example. Sudoku](https://github.com/Shiyan7/sudoku-effector)

This post may cause 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!