DeepFrontend
Practice ArenaBlogSign in
Go Pro
DeepFrontend

Interview-grade learning paths and hands-on practice for mid-to-senior engineers. Master internals, patterns, and system architecture with runnable code.

All systems operational

Core Courses

  • -JavaScript Internals
  • -React Reconciliation
  • -TypeScript rigor
  • -Next.js Caching
  • -Node.js Event Loop
  • -System Design
  • -Web Security
  • -CSS & Page Layouts

Explore

  • Learning Paths
  • Practice Arena
  • Pricing Options
  • HTML Sitemap

Resources

  • Privacy Policy
  • Terms of Service
  • Email Support

© 2026 DeepFrontend. All rights reserved.

Expert learning environments for web engineering teams.

Home/Frontend Architecture/Folder Structure & Feature-Based Architecture
intermediate20 min read·Updated Jul 2026Expert reviewed

Folder Structure & Feature-Based Architecture

Technical debt is often just poor folder structure. Moving from file-type grouping (controllers, components, views) to domain/feature-based grouping prevents 'file-hopping' and enables modules to be self-contained and deleted easily.

folder-structurefeature-basedclean-architecturerefactoringmonolith

Knowledge Check

2 questions · pass at 70%

0/2
easymcq

1. What is the primary benefit of feature-based folder organization?


Interview Questions

1 questions

Cheatsheet

Download-ready reference
Cheatsheet
File-type layout  groups by file role (components/, hooks/, api/). Good for tiny apps.
Feature layout    groups by business domain (features/billing/, features/auth/). Scale-ready.

Strict Boundaries:
- Use index.ts inside each feature folder as the only export gate.
- Prevent external code from importing internal folders directly.
- ESLint rule "no-restricted-imports" enforces this boundary.

Related topics

Module Systems (ESM vs CommonJS)ProDesign Patterns & Clean ArchitectureProAtomic DesignPro

On this page

20m
Knowledge CheckInterview QuestionsCheatsheet

Concept#

File-type grouping vs Feature-based grouping#

In early development stages, most codebases start with file-type grouping (screaming architecture anomaly):

src/
├── components/
│   ├── UserProfile.tsx
│   └── UserSettings.tsx
├── hooks/
│   ├── useUser.ts
│   └── useSettings.ts
└── services/
    ├── userService.ts
    └── settingsService.ts

As the app grows, adding or modifying a single feature requires file-hopping across multiple folders. This increases cognitive load and results in loose coupling of features.

Feature-based grouping consolidates related files into one folder representing a business domain or feature:

src/
├── features/
│   ├── auth/
│   └── billing/
│       ├── components/
│       │   ├── PricingTable.tsx
│       │   └── CheckoutButton.tsx
│       ├── hooks/
│       │   └── useSubscription.ts
│       ├── api/
│       │   └── billingClient.ts
│       └── index.ts  <-- PUBLIC API

Public API boundaries via index.ts#

To keep features decoupled, they must communicate only through a strict public interface. The index.ts file at the feature root acts as a barrel file containing explicit exports.

Other features must never import internal files directly:

// ❌ WRONG: importing internals breaks encapsulation
import { CheckoutButton } from '../billing/components/CheckoutButton';
 
//  CORRECT: importing through feature public API
import { CheckoutButton } from '../billing';

Use ESLint rules (no-restricted-imports) to block direct imports of internal directories.


Common Mistakes#

1. The "shared" folder dumping ground#

When components are reused, developers throw them into a global shared/ or common/ folder. This folder becomes a massive junk drawer. Keep components inside feature folders until they are genuinely needed by multiple unrelated domains.

2. Deeply nested feature subdirectories#

Avoid nesting feature folders more than 2-3 levels deep. Deep nesting makes file paths hard to read and import.


Best Practices#

  • Self-contained features: A feature folder should contain its own assets, tests, styles, state management, and routes.
  • Easy deletion: If a feature is deprecated, you should be able to delete the entire feature folder without breaking the rest of the application.
  • Enforce boundaries: Use tooling (like Dependency Cruiser or Nx boundaries) to enforce that features cannot import from each other's internals.