Explaining what Feature-Sliced Design is — a frontend modular architecture methodology based on dividing a project by business features rather than technical layers. Unlike the classic layered architecture (controllers, services, repositories), FSD groups code by the functional capabilities of the application: each feature contains its own logic, UI, and data. According to the State of Frontend 2024 survey, 23% of React developers use FSD as their primary architectural methodology, making it the second most popular after pure Feature-based structure.
Key Takeaways
Feature-Sliced Design (FSD) is a frontend application architecture methodology first proposed in 2021 by the feature-sliced.design community. The core idea of FSD is grouping code by business features (slices), each of which is a self-contained unit: it contains its own business logic, user interface, API interaction, data models, and tests. This distinguishes FSD from classic layered architecture where code is divided by technical criteria (controller, service, repository).
The methodology borrows concepts from Domain-Driven Design (DDD) and Bounded Context: each application feature is a separate bounded context with clear boundaries. Changes inside one feature should not break other features if they only use the public API of the slice. According to the State of Frontend 2024 survey, FSD ranks second in popularity among React architectures (23%), second only to the informal Feature-based structure (31%).
In mobile development, FSD adapts to the specifics of Android modules and iOS frameworks. At IT Sectr, we use FSD for projects with 10+ screens and 3+ teams — the methodology allows independent feature development and reduces git conflicts by 40% compared to a monorepo without slice boundaries.
FSD defines seven hierarchical layers, each containing code of a certain abstraction level. The main architectural rule is that layers can only import code from layers below. Violating this rule (importing the features layer into entities) is considered an architectural error and is blocked by a linter.
| Layer | Purpose | Imports |
|---|---|---|
| app | Application initialization, providers, global styles, routing | Any layers |
| processes | Business processes combining multiple features (onboarding, payment) | pages, features, entities, shared |
| pages | Feature composition on a page, page routing | features, entities, shared |
| features | User scenarios: login form, favorites list, search filter | entities, shared |
| entities | Business entities: User, Product, Order, Cart | shared |
| widgets | Composite UI components: Header, Sidebar, ArticleCard | shared, entities |
| shared | Utilities, UI-kit, API client, configs — independent of business logic | Only external libraries |
Example directory structure of an FSD project:
src/
├── app/ // Application layer
│ ├── providers/
│ ├── router/
│ └── styles/
├── pages/ // Pages — feature composition
│ └── main/
├── features/ // Features — user scenarios
│ ├── auth/ // Slice «Authentication»
│ │ ├── ui/
│ │ ├── model/
│ │ └── api/
│ └── productList/ // Slice «Product List»
│ ├── ui/
│ └── model/
├── entities/ // Business entities
│ ├── user/
│ └── product/
├── widgets/ // Composite components
│ └── header/
└── shared/ // Shared utilities and UI-kit
└── ui/The «layers look only downward» rule is the cornerstone of FSD. If feature auth imports entity user — that is correct. If entity user starts importing feature auth — that is a cyclic dependency and a violation of isolation. To enforce this rule, ESLint plugins (eslint-plugin-fsd) or custom linters of slice public APIs are used.
Slice — the main grouping unit in FSD, corresponding to one business feature or entity. Each slice resides within one of the seven layers (features, entities, widgets, pages) and contains a complete set of code for implementing specific functionality: UI components, data model, API client, constants, and tests.
Slice boundaries are defined by the business domain: feature auth includes everything related to authorization (login form, registration form, password reset); entity user includes the User model, UserRepository, and serialization. Boundaries should not overlap: if feature auth needs user data — it imports entity user rather than duplicating the logic. In mobile development, an FSD slice often corresponds to a Gradle module in Android or a Swift package in iOS.
Slices are strictly isolated: the internal structure of one slice is invisible to other slices. For interaction between slices, a public API is used — an index.ts/index.js file that exports only what is allowed for external use. Everything else is private modules. This approach prevents accidental dependencies and simplifies refactoring: changing the private implementation of one slice does not affect other slices.
Inside each FSD slice, code is further organized by segments — technical categories that repeat across all slices. The standard set of segments includes ui (interface components), model (business logic, Store, Actions, Reducer), api (server requests, mutations), lib (utilities and helpers), and config (feature configuration).
| Segment | Contents | Example |
|---|---|---|
| ui/ | React/Vue/SwiftUI components, styles, Storybook | LoginForm.tsx, login.module.css |
| model/ | Store, Reducer, Actions, types, contracts | LoginStore.ts, authReducer.ts |
| api/ | HTTP clients, mutations, RPC calls | authApi.ts, loginMutation.ts |
| lib/ | Helper functions, validators | validateEmail.ts, formatPhone.ts |
| config/ | Constants, feature configuration | authConfig.ts, endpoints.ts |
Segments are a recommendation, not a strict rule. If a slice is small, segments can be merged. For large slices (a feature with 10+ files), segmentation is mandatory — without it, the internal structure quickly turns into a «basket» of 50 files where finding the needed component takes minutes. In mobile development, segments are often replaced with a file structure by type: each feature is a separate Swift file or Kotlin class with internal types.
In mobile development, FSD adapts to platform-specific features — the modular structure of Android (Gradle modules) and Swift Package Manager. Android adaptation assumes that each slice is a separate Gradle module with its own build.gradle. Modules feature-auth, feature-profile, entity-user, shared-ui are isolated from each other at the build level: feature-auth cannot import feature-profile unless specified in dependencies.
iOS adaptation is built on Swift Package Manager: each slice is a Swift package with a public API. In TCA projects, the feature.auth slice contains its own Reducer, Store, View, and API client. According to the Swift Community Survey 2024, 28% of iOS projects with TCA use a slice architecture close to FSD.
The main challenge of mobile FSD adaptation is duplication of the shared layer. In mobile development, UI components (shared/ui) often depend on the platform (Android Views vs Jetpack Compose vs SwiftUI), which requires separate shared modules for each technology. In FSD, the shared layer is usually platform-independent (utilities, configs), while the UI-kit is moved to a separate module or component library.
Advantages of FSD become noticeable in large projects with 10+ developers. Each developer or team works on their own slice without touching others' code. Git conflicts are reduced by 40–60% (data from feature-sliced.design case studies). New features are added without the risk of breaking existing ones, provided they only use the public API of slices. Refactoring one feature does not require changes to others — just rewrite ui/model/api inside one slice while keeping the public API intact.
| Aspect | FSD | Feature-based (without FSD) | Layered Architecture |
|---|---|---|---|
| Feature isolation | Strict | Medium | Low |
| Parallel development | 10+ teams | 3–5 teams | 1–2 teams |
| Cross-project reuse | Yes (slice packages) | Only via copy-paste | Via shared modules |
| Entry barrier | High | Low | Medium |
| Gradle isolation (Android) | Native (modules) | Native (modules) | Weak |
Disadvantages of FSD — excessive nesting for small projects. If an application consists of 3–5 screens, seven layers and segmentation inside each slice create more organizational code than the application itself. The entry barrier is high: new developers spend 2–4 weeks learning the methodology. Also, FSD is poorly compatible with rapid prototyping — prototyping requires frequent cross-layer imports, which are prohibited in FSD and slow down iterations.
It is recommended to start with a simpler Feature-based structure and migrate to FSD when the number of screens exceeds 20 and the team grows beyond 5 developers.
Frequently Asked Questions
Feature-based architecture groups code by features without strict import rules — feature Auth can import another feature Profile without restrictions. FSD adds a layer hierarchy and the «layers look only downward» rule. In Feature-based, entity and feature can be at the same level and import each other; in FSD, entity lies below feature, and feature imports entity, not vice versa. Feature-based is suitable for small projects, FSD for large ones.
Slice isolation simplifies unit testing — each slice is tested independently by mocking dependencies of the underlying layers. For feature auth, it is enough to mock entity user. Integration tests verify the public API of the slice. In Android, a feature's Gradle module contains its own test directory with tests for the Reducer, API client, and UI (via Compose Test). In iOS, a slice package includes tests for all segments.
Yes, FSD works well with Jetpack Compose, especially in multi-module Android projects. Each slice is a separate Gradle module with a public API via the exported directive. The features layer contains Composable features (LoginFeature, ProductListFeature), the entities layer contains data classes and Repository, and shared contains the UI-kit (MaterialTheme-wrapper, custom components). FSD is recommended for large Compose projects with 5+ developers.
The mandatory layers are app, shared, entities, and features. The rest (processes, pages, widgets) are optional and added as needed. In mobile development, the pages layer is often merged with navigation routing, and widgets are replaced by shared/ui-kit. Processes are typically not used in mobile projects — their role is fulfilled by the domain layer or business logic in ViewModel. The main thing is to follow the import hierarchy rule.
FSD borrows from DDD the concepts of Bounded Context and Ubiquitous Language. Each slice corresponds to a bounded context — a boundary within which terms have an unambiguous meaning. Inside the slice, a unified language (ubiquitous language) is used, understood by both developers and business analysts. For example, in the auth slice, the terms «login», «password», «token» have the same meaning for all team members, which reduces misunderstandings between analysts and developers by 30–50%.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also