A Better Way to Organize Your Front-End Projects: Component-Focused Architecture (CFA)
After years of working as a front-end developer, I’ve realized that following the most popular architecture approach isn’t necessarily the right choice. Every project is different, so forcing them all into the same mold is doomed to fail. What might seem clean at first will quickly turn into a codebase that’s hard to navigate. Most existing approaches focus on abstraction and emphasizing logic, forgetting that front-end is primarily about the UI. While separating logic from views is good practice, prioritizing logic too much often leads to a mess. Through trial and error, I eventually developed my own approach to structuring my projects. The goal is to separate logic from components, prioritize UI, and enforce consistent patterns to simplify future refactors. Who is this for? Given my focus on React and Next.js, my article is mainly aimed at other developers working with these frameworks—whether you’re just starting out or have years of experience under your belt. It’s useful for both solo developers and team projects, offering insights that could revolutionize the way you structure your code. Even if front end is not your main focus, you might still find this article valuable for understanding how UI architectures fit into the bigger picture. Why I made this Structures like FSD or MVVM often scatter a single component's functionality across multiple layers. Something as simple as updating a UI element might require jumping between several files and folders just to understand what’s going on. While it might not seem like a big deal when you’re working on a project alone, it becomes especially painful in a team setting. Such abstractions lead to teams spending more time debating what goes where instead of actually coding. Each developer ends up with their own interpretation of the structure, and before you know it, the codebase turns into a mess that no one wants to touch. That’s how you get a legacy project that everyone hopes won’t collapse before they have to rewrite the whole thing. My goal is to improve the overall developer experience by offering a fresh perspective on structuring front-end projects. I also enforce consistent patterns for components and utilities to simplify potential refactors and make development more intuitive—so you can focus on building, and not just organizing. Key features Clarity. A structure that grows with your project, allowing it to remain clean and easy to navigate. Separation of concerns. While logic is important, the UI is always prioritized. Logic-heavy components are kept separate from presentational components. Consistency. A top-down hierarchy with clear responsibilities. Layers can only import from those below them, never sideways or upwards. No global barrel files. Avoiding global index files helps you maintain predictable imports, prevent circular imports, and ensure faster build times. Scoped folders. Each component or utility lives in its own folder, with all related styles, types, logic and other dependencies grouped together. How it’s organized Here’s a quick overview of the main layers: app/ — Your app’s entry point (usage may vary depending on your framework) pages/ — Optional. Full page components, page-specific logic, or file-based routing with the Pages Router in older Next.js versions. features/ — Logic-heavy components (actions, widgets, fetchers) that manage business workflows and API interactions. ui/ — Reusable presentational units, split into components and elements. shared/ — Global utilities like hooks, functions, types and API slices. I designed this structure around a top-down dependency flow, scoped folders, no global barrel files and consistent kebab-case naming. It’s meant to keep code predictable, easy to scale, and pleasant to work with. If you want to dive deeper and see how you can adapt CFA to your own projects, the full documentation is available on my GitHub. That’s it for now! I’m sure this approach will make your development process more efficient, and I’m always open to feedback. If you have any questions or suggestions, feel free to reach out. Happy coding!

After years of working as a front-end developer, I’ve realized that following the most popular architecture approach isn’t necessarily the right choice. Every project is different, so forcing them all into the same mold is doomed to fail. What might seem clean at first will quickly turn into a codebase that’s hard to navigate.
Most existing approaches focus on abstraction and emphasizing logic, forgetting that front-end is primarily about the UI. While separating logic from views is good practice, prioritizing logic too much often leads to a mess.
Through trial and error, I eventually developed my own approach to structuring my projects. The goal is to separate logic from components, prioritize UI, and enforce consistent patterns to simplify future refactors.
Who is this for?
Given my focus on React and Next.js, my article is mainly aimed at other developers working with these frameworks—whether you’re just starting out or have years of experience under your belt. It’s useful for both solo developers and team projects, offering insights that could revolutionize the way you structure your code. Even if front end is not your main focus, you might still find this article valuable for understanding how UI architectures fit into the bigger picture.
Why I made this
Structures like FSD or MVVM often scatter a single component's functionality across multiple layers. Something as simple as updating a UI element might require jumping between several files and folders just to understand what’s going on. While it might not seem like a big deal when you’re working on a project alone, it becomes especially painful in a team setting.
Such abstractions lead to teams spending more time debating what goes where instead of actually coding. Each developer ends up with their own interpretation of the structure, and before you know it, the codebase turns into a mess that no one wants to touch. That’s how you get a legacy project that everyone hopes won’t collapse before they have to rewrite the whole thing.
My goal is to improve the overall developer experience by offering a fresh perspective on structuring front-end projects. I also enforce consistent patterns for components and utilities to simplify potential refactors and make development more intuitive—so you can focus on building, and not just organizing.
Key features
- Clarity. A structure that grows with your project, allowing it to remain clean and easy to navigate.
- Separation of concerns. While logic is important, the UI is always prioritized. Logic-heavy components are kept separate from presentational components.
- Consistency. A top-down hierarchy with clear responsibilities. Layers can only import from those below them, never sideways or upwards.
- No global barrel files. Avoiding global index files helps you maintain predictable imports, prevent circular imports, and ensure faster build times.
- Scoped folders. Each component or utility lives in its own folder, with all related styles, types, logic and other dependencies grouped together.
How it’s organized
Here’s a quick overview of the main layers:
-
app/
— Your app’s entry point (usage may vary depending on your framework) -
pages/
— Optional. Full page components, page-specific logic, or file-based routing with the Pages Router in older Next.js versions. -
features/
— Logic-heavy components (actions, widgets, fetchers) that manage business workflows and API interactions. -
ui/
— Reusable presentational units, split into components and elements. -
shared/
— Global utilities like hooks, functions, types and API slices.
I designed this structure around a top-down dependency flow, scoped folders, no global barrel files and consistent kebab-case naming. It’s meant to keep code predictable, easy to scale, and pleasant to work with.
If you want to dive deeper and see how you can adapt CFA to your own projects, the full documentation is available on my GitHub.
That’s it for now! I’m sure this approach will make your development process more efficient, and I’m always open to feedback. If you have any questions or suggestions, feel free to reach out.
Happy coding!