Feature-Sliced Design (FSD)
Relevant source files
The following files were used as context for generating this wiki page:
This project adopts Feature-Sliced Design (FSD) as its primary architectural methodology. The core goal is to move from "building components" to "architecting systems" by creating a scalable, maintainable, and resilient codebase. FSD achieves this by organizing the application into distinct layers, each with a specific responsibility, which enforces a unidirectional data flow and decouples business logic from the UI.
This approach ensures that dependencies are predictable and prevents the "spaghetti code" that can arise in large applications. The structure is designed to be intuitive for developers, making it easier to locate code, understand its scope, and add new features without introducing side effects.
Sources: README.md:21-25, 30-32
Architectural Layers
The FSD architecture in this project is organized into a hierarchy of layers. A key rule is that a layer can only depend on layers strictly below it. For example, a widget can use an entity, but an entity cannot use a widget. This creates a clear and enforceable dependency graph.
The following diagram illustrates the FSD layers present in this repository and their dependency flow.
This diagram shows the hierarchical structure of the FSD layers, where upper layers can depend on lower layers, but not vice-versa.
Sources: README.md:30-32, project file structure
Layer Breakdown
| Layer | Responsibility | Examples |
|---|---|---|
app | Initializes the app, sets up providers, routing, and global styles. | App.tsx, index.css, ThemeProvider |
pages | Composes widgets and entities to form complete application pages. | Home.tsx, Projects.tsx |
widgets | Composite, self-contained UI blocks that combine entities and features. | Navbar.tsx, Hero.tsx, Footer.tsx |
entities | Core business entities of the application, including their data and UI. | ProjectCard.tsx, project/model/data.ts |
shared | Reusable, framework-agnostic code used across the entire application. | Button.tsx, config/content.ts, lib/utils.ts |
Sources: README.md:30-32, src/app/App.tsx, src/pages/Home.tsx, src/widgets/Hero/Hero.tsx, src/entities/project/ui/ProjectCard.tsx, src/shared/config/content.ts
app Layer
The app layer is the entry point and root of the application. It is responsible for assembling all other parts of the application.
Key responsibilities include:
- Global Providers: Wrapping the application in context providers, such as
ThemeProviderandBrowserRouter(fromreact-router-dom). - Routing: Defining the application's routes and mapping them to their corresponding
pages. - Global Layout: Rendering universal layout components like
NavbarandFooter. - Global Styles: Importing and applying global CSS.
// src/app/App.tsx:18-28
const App = () => {
const fallback = (
<PageSkeleton>
<PageContentSkeleton />
</PageSkeleton>
);
return (
<ThemeProvider>
<ScrollToTop />
<div className="min-h-screen bg-background text-text-primary transition-colors duration-300 flex flex-col">
<Navbar />
<div className="grow">
<Routes>
{/* ... Route definitions ... */}
</Routes>
</div>
<Footer />
</div>
</ThemeProvider>
);
};
Sources: src/app/App.tsx, src/app/index.css
pages Layer
The pages layer consists of components that represent full pages of the application. These components are responsible for composing widgets and entities into a coherent user view. Pages are lazy-loaded in App.tsx to improve initial load performance.
The Home.tsx page, for example, assembles several widgets to build the landing page.
This diagram shows how the Home.tsx page is constructed by composing various widgets.
Sources: src/pages/Home.tsx:7-29, src/app/App.tsx:11-16
widgets Layer
Widgets are complex, self-contained components that encapsulate a piece of business logic and UI. They are composed of smaller entities and shared components. A good example is the HomeProjectsSection widget, which displays a curated list of projects.
This widget:
- Imports
projectsDatafrom theprojectentity. - Imports the
ProjectCardUI component from theprojectentity. - Imports configuration text from
shared/config/content.ts. - Arranges these pieces into a section with a title, subtitle, and a grid of project cards.
// src/widgets/HomeProjectsSection/HomeProjectsSection.tsx:1-7
import { Link } from "react-router-dom";
import { ArrowRight, Briefcase } from "lucide-react";
import { projectsData } from "@/entities/project/model/data";
import { ProjectCard } from "@/entities/project/ui/ProjectCard";
import { homeContent } from "@/shared/config/content";
Sources: src/widgets/HomeProjectsSection/HomeProjectsSection.tsx, src/widgets/Hero/Hero.tsx
entities Layer
Entities are the core business objects of the application. In FSD, an entity is represented by a "slice" that contains its data model, UI components, and any related logic. The project entity is a clear example.
The project entity slice is structured as follows:
model/: Contains the data and types for projects.data.ts: An array ofProjectCardDataobjects, serving as a mock database.types.ts: TypeScript interfaces for the project data structure.
ui/: Contains React components for rendering the entity.ProjectCard.tsx: A component that displays a single project.ProjectsCarousel.tsx: A component to display projects in a carousel format.
This separation within the entity slice allows the data model to be used independently of its UI representation.
This diagram shows the internal structure of the project entity and how its parts are consumed by higher-level layers.
Sources: src/entities/project/model/data.ts, src/entities/project/ui/ProjectCard.tsx, src/pages/Projects.tsx:2-3
shared Layer
The shared layer is the lowest level of the architecture. It contains reusable, application-agnostic code that can be used by any layer above it. This layer must not have any dependencies on other layers (features, entities, widgets, pages, app).
This layer is typically organized into subdirectories based on the type of code:
config/: Global application configuration and static content, likecontent.ts.lib/: Utility functions, such asutils.ts(forcn) andScrollToTop.tsx.ui/: Primitive, reusable UI components likeButton,Container,Logo, andBentoGrid.ui/skeletons/: Loading state skeletons likePageContentSkeleton.
The shared/config/content.ts file centralizes all static text content, making it easy to manage and update UI copy without touching component logic.
Sources: src/shared/config/content.ts, src/shared/ui/skeletons/PageContentSkeleton.tsx, src/widgets/Footer/Footer.tsx:15
Conclusion
The implementation of Feature-Sliced Design in this portfolio provides a robust and scalable foundation. By strictly separating concerns into layers (app, pages, widgets, entities, shared) and enforcing a unidirectional dependency flow, the architecture promotes code reusability, simplifies maintenance, and enhances developer productivity. This structured approach is a clear example of "architecting a system," ensuring the application remains organized and resilient as it evolves.
Sources: README.md:21-25, 30-32