React Tutorial 0/120 lessons ~6 min read Lesson 9

    React Folder Structure

    React Folder Structure explains scalable frontend organization through feature boundaries, shared UI, pages, hooks, services, types, utilities, assets, dependency direction, co-location, team ownership, and enterprise architecture.

    Course progress0%
    Focus
    51 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Learning Objectives

    By the end of this lesson, you will be able to:

    1. Understand why folder structure matters in React applications.
    2. Understand the difference between project structure and application architecture.
    3. Understand the purpose of src, public, and configuration files.
    4. Organize components effectively.
    5. Understand feature-based folder organization.
    6. Separate reusable UI from business-specific components.
    7. Organize pages, hooks, services, utilities, types, and assets.
    8. Understand dependency direction between folders.
    9. Design a scalable structure for medium and large React applications.
    10. Avoid common folder-structure mistakes.
    11. Understand how folder structure affects team scalability.
    12. Design a React structure suitable for an enterprise application.
    13. Explain folder-structure decisions confidently in interviews.

    Introduction

    A React application can start very simply:

    text
    src/
    ├── App.tsx
    └── main.tsx

    That is perfectly fine.

    But after a few months, a real application might contain:

    text
    200+ Components
    50+ Hooks
    100+ API Functions
    30+ Pages
    Multiple Business Domains
    Shared UI
    Authentication
    State Management
    Testing
    Analytics
    Feature Flags

    If everything is placed into a few folders without clear boundaries, the project becomes difficult to understand.

    For example:

    text
    src/
    └── components/
    ├── Button.tsx
    ├── CourseCard.tsx
    ├── PaymentForm.tsx
    ├── UserProfile.tsx
    ├── Dashboard.tsx
    ├── Login.tsx
    ├── AdminPanel.tsx
    ├── useAuth.ts
    ├── api.ts
    ├── utils.ts
    └── ...

    This technically works.

    But it doesn't communicate the architecture.

    A good folder structure should answer:

    Where does this code belong, who owns it, and what is it allowed to depend on?

    Folder Structure Is Not Architecture

    This distinction is extremely important for senior engineers.

    A folder structure describes:

    text
    Where files live

    Architecture describes:

    text
    Responsibilities
    Dependencies
    Boundaries
    Data flow
    Communication
    Ownership
    Runtime behavior

    For example, this looks organized:

    text
    src/
    ├── components/
    ├── services/
    ├── hooks/
    └── utils/

    But it doesn't tell us:

    text
    Who can import whom?
    Which code belongs to which business domain?
    Where should authentication logic live?
    Can payment code directly access course internals?

    Therefore:

    A clean folder structure can support good architecture, but it does not automatically create good architecture.

    Start With the Basic Structure

    A new React + TypeScript + Vite project may look approximately like:

    text
    techlearningpro-react/
    │
    ├── public/
    │
    ├── src/
    │ ├── assets/
    │ ├── App.tsx
    │ ├── App.css
    │ ├── index.css
    │ └── main.tsx
    │
    ├── .gitignore
    ├── index.html
    ├── package.json
    ├── package-lock.json
    ├── tsconfig.json
    ├── tsconfig.app.json
    ├── tsconfig.node.json
    └── vite.config.ts

    The exact generated structure can vary by Vite version and project configuration.

    For this lesson, we're interested primarily in:

    text
    src/
    public/
    configuration

    High-Level Structure

    For a production-oriented application, think about the project in layers:

    text
    React Project
    │
    ├── Application Source
    │ └── src/
    │
    ├── Static Assets
    │ └── public/
    │
    ├── Build Configuration
    │ └── vite.config.ts
    │
    ├── Dependency Configuration
    │ └── package.json
    │
    ├── TypeScript Configuration
    │ └── tsconfig*.json
    │
    └── Environment Configuration
    └── .env*

    Then inside src:

    text
    src/
    │
    ├── app/
    ├── features/
    ├── components/
    ├── pages/
    ├── hooks/
    ├── services/
    ├── types/
    ├── utils/
    └── assets/

    This is a scalable starting point, not a mandatory rule.

    The src Directory

    src contains the application's source code.

    A mature application might look like:

    text
    src/
    │
    ├── app/
    ├── features/
    ├── components/
    ├── pages/
    ├── hooks/
    ├── services/
    ├── types/
    ├── utils/
    ├── assets/
    └── main.tsx

    Think of src as:

    text
    Business + UI + Application Logic

    The app Folder

    The app folder can contain application-level configuration and composition.

    For example:

    text
    src/
    └── app/
    ├── App.tsx
    ├── routes/
    ├── providers/
    ├── config/
    └── store/

    Typical responsibilities:

    text
    app/
    ├── Application bootstrap
    ├── Routing
    ├── Global providers
    ├── Application configuration
    └── Global state setup

    For example:

    tsx
    function App() {
    return (
    <AuthProvider>
    <ThemeProvider>
    <RouterProvider />
    </ThemeProvider>
    </AuthProvider>
    );
    }

    This is application composition.

    The features Folder

    For large applications, this is one of the most valuable folders.

    Instead of organizing everything by technical type:

    text
    components/
    hooks/
    services/

    you can organize around business capabilities:

    text
    features/
    ├── authentication/
    ├── courses/
    ├── learning/
    ├── payments/
    └── profile/

    Each feature can contain its own:

    text
    components
    hooks
    services
    types
    pages
    tests

    For example:

    text
    features/
    └── courses/
    ├── components/
    ├── hooks/
    ├── services/
    ├── types/
    ├── pages/
    └── tests/

    This creates a strong business boundary.

    Why Feature-Based Structure?

    Imagine you are asked:

    Where is the course enrollment logic?

    With a feature-based architecture:

    text
    features/
    └── courses/

    You immediately know where to look.

    Without it:

    text
    components/
    hooks/
    services/
    utils/
    pages/

    you may need to search across the entire application.

    Feature-based organization provides locality.

    Related code stays together.

    Example: TechLearningPro

    Imagine TechLearningPro has:

    text
    features/
    ├── authentication/
    ├── courses/
    ├── learning/
    ├── quizzes/
    ├── certificates/
    ├── payments/
    └── user-profile/

    Now the business domain becomes visible from the folder structure.

    text
    TechLearningPro
    │
    ├── Authentication
    ├── Courses
    ├── Learning
    ├── Quizzes
    ├── Certificates
    ├── Payments
    └── User Profile

    This is more meaningful than:

    text
    components/
    services/
    hooks/
    utils/

    alone.

    Feature Structure Example

    Consider:

    text
    features/
    └── courses/
    │
    ├── components/
    │ ├── CourseCard.tsx
    │ ├── CourseList.tsx
    │ └── CourseProgress.tsx
    │
    ├── hooks/
    │ └── useCourses.ts
    │
    ├── services/
    │ └── courseService.ts
    │
    ├── types/
    │ └── course.types.ts
    │
    ├── pages/
    │ ├── CoursesPage.tsx
    │ └── CourseDetailsPage.tsx
    │
    └── tests/

    Now everything related to courses is close together.

    The components Folder

    The shared components folder should generally contain reusable UI components.

    For example:

    text
    components/
    ├── Button/
    ├── Modal/
    ├── Input/
    ├── DataTable/
    ├── Spinner/
    ├── Card/
    └── ErrorBoundary/

    These components should ideally be reusable across multiple features.

    For example:

    tsx
    <Button>
    Save
    </Button>

    could be used by:

    text
    Courses
    Payments
    Profile
    Authentication
    Admin

    Shared Component vs Feature Component

    This distinction is critical.

    Shared

    text
    components/
    └── Button/

    The Button doesn't know anything about courses.

    Feature-specific

    text
    features/
    └── courses/
    └── components/
    └── CourseCard.tsx

    CourseCard understands course-specific concepts.

    Therefore:

    text
    Button
    ↓
    Generic
    CourseCard
    ↓
    Business-specific

    Don't move everything into components just because it's technically a component.

    The pages Folder

    Pages represent larger UI compositions or route-level screens.

    For example:

    text
    pages/
    ├── HomePage.tsx
    ├── LoginPage.tsx
    ├── DashboardPage.tsx
    ├── NotFoundPage.tsx
    └── SettingsPage.tsx

    A page typically composes:

    text
    Page
    │
    ├── Shared components
    ├── Feature components
    ├── Layout
    └── Page-specific behavior

    For example:

    tsx
    function CoursesPage() {
    return (
    <CourseLayout>
    <CourseHeader />
    <CourseFilters />
    <CourseList />
    </CourseLayout>
    );
    }

    Pages vs Features

    You may ask:

    If courses have pages, why have both pages and features?

    There are multiple valid approaches.

    Centralized pages

    text
    src/
    ├── pages/
    │ ├── HomePage.tsx
    │ └── CourseDetailsPage.tsx
    │
    └── features/
    └── courses/

    Feature-owned pages

    text
    src/
    └── features/
    └── courses/
    └── pages/
    ├── CoursesPage.tsx
    └── CourseDetailsPage.tsx

    For a large domain-driven application, feature-owned pages can improve locality.

    For a smaller application, a central pages directory may be simpler.

    There is no universal rule.

    The hooks Folder

    Reusable custom hooks can live under:

    text
    hooks/

    For example:

    text
    hooks/
    ├── useDebounce.ts
    ├── useLocalStorage.ts
    ├── useMediaQuery.ts
    └── usePrevious.ts

    A hook should represent reusable React behavior.

    Example:

    tsx
    function useDebounce<T>(
    value: T,
    delay: number
    ) {
    // ...
    }

    Feature-Specific Hooks

    Not every hook belongs in the global hooks directory.

    For example:

    text
    features/
    └── courses/
    └── hooks/
    └── useCourseSearch.ts

    This hook understands course-specific behavior.

    Whereas:

    text
    hooks/
    └── useDebounce.ts

    is generic.

    Think:

    text
    Global hook
    ↓
    Generic behavior
    Feature hook
    ↓
    Business-specific behavior

    The services Folder

    Services generally contain external communication or application-level service logic.

    For example:

    text
    services/
    ├── httpClient.ts
    ├── authService.ts
    ├── analyticsService.ts
    └── storageService.ts

    A service might contain:

    tsx
    export async function fetchCourses() {
    const response = await fetch("/api/courses");
    return response.json();
    }

    The component shouldn't necessarily contain all API implementation details.

    Feature-Specific Services

    Again, locality matters.

    Instead of:

    text
    services/
    ├── authService.ts
    ├── courseService.ts
    ├── paymentService.ts

    you could use:

    text
    features/
    ├── authentication/
    │ └── services/
    │ └── authService.ts
    │
    ├── courses/
    │ └── services/
    │ └── courseService.ts
    │
    └── payments/
    └── services/
    └── paymentService.ts

    This makes ownership clearer.

    The types Folder

    Shared TypeScript types can live in:

    text
    types/

    For example:

    text
    types/
    ├── api.ts
    ├── pagination.ts
    ├── user.ts
    └── common.ts

    Example:

    tsx
    export interface ApiResponse<T> {
    data: T;
    message?: string;
    }

    But don't create a giant global type folder containing every type in the application.

    Prefer feature-local types when they belong to one domain.

    Feature-Specific Types

    For example:

    text
    features/
    └── courses/
    └── types/
    ├── course.ts
    ├── lesson.ts
    └── enrollment.ts

    This is better than putting every domain type into:

    text
    src/types/

    when those types aren't actually shared.

    The utils Folder

    Utilities are small, generic functions.

    For example:

    text
    utils/
    ├── date.ts
    ├── currency.ts
    ├── validation.ts
    └── string.ts

    Example:

    tsx
    export function formatCurrency(
    amount: number
    ) {
    return new Intl.NumberFormat(
    "en-IN",
    {
    style: "currency",
    currency: "INR"
    }
    ).format(amount);
    }

    A utility should ideally be:

    text
    Pure
    Generic
    Reusable
    Easy to test

    Avoid the "Utils Junk Drawer"

    One of the most common mistakes is:

    text
    utils/
    ├── helper.ts
    ├── common.ts
    ├── misc.ts
    ├── temp.ts
    ├── newHelper.ts
    └── finalUtils.ts

    This becomes a junk drawer.

    Instead, ask:

    What responsibility does this utility have?

    For example:

    text
    utils/
    ├── date/
    ├── currency/
    ├── validation/
    └── formatting/

    Clear names communicate intent.

    The assets Folder

    Application assets can be organized under:

    text
    assets/
    ├── images/
    ├── icons/
    ├── fonts/
    └── styles/

    For example:

    text
    assets/
    └── images/
    ├── logo.png
    ├── hero.webp
    └── courses/

    Assets imported into application code can live here.

    Static public files that should be served directly can instead live under:

    text
    public/

    CSS Organization

    There are several valid approaches.

    Component-level CSS

    text
    Button/
    ├── Button.tsx
    └── Button.css

    CSS Modules

    text
    Button/
    ├── Button.tsx
    └── Button.module.css

    Global styles

    text
    src/
    └── styles/
    ├── globals.css
    ├── variables.css
    └── typography.css

    CSS-in-JS / other styling systems

    These are architectural choices.

    The important thing is consistency.

    A Small React Application

    Don't over-engineer.

    For a small application:

    text
    src/
    ├── components/
    ├── pages/
    ├── hooks/
    ├── services/
    ├── App.tsx
    └── main.tsx

    may be enough.

    You don't need:

    text
    app/
    features/
    domains/
    modules/
    shared/
    infrastructure/

    from day one.

    Medium Application

    As complexity grows:

    text
    src/
    ├── components/
    ├── features/
    ├── hooks/
    ├── pages/
    ├── services/
    ├── types/
    ├── utils/
    ├── assets/
    ├── App.tsx
    └── main.tsx

    Now business features can start owning their code.

    Large Application

    A large application might use:

    text
    src/
    │
    ├── app/
    │
    ├── features/
    │ ├── authentication/
    │ ├── courses/
    │ ├── payments/
    │ ├── learning/
    │ └── notifications/
    │
    ├── components/
    │
    ├── hooks/
    │
    ├── services/
    │
    ├── types/
    │
    ├── utils/
    │
    ├── assets/
    │
    └── main.tsx

    This structure gives us a balance between:

    text
    Business boundaries
    +
    Shared infrastructure

    Enterprise Structure

    For a larger enterprise system, you might evolve toward:

    text
    src/
    │
    ├── app/
    │ ├── App.tsx
    │ ├── routes/
    │ ├── providers/
    │ ├── config/
    │ └── store/
    │
    ├── features/
    │ ├── authentication/
    │ │ ├── components/
    │ │ ├── hooks/
    │ │ ├── services/
    │ │ ├── types/
    │ │ ├── pages/
    │ │ └── tests/
    │ │
    │ ├── courses/
    │ │ ├── components/
    │ │ ├── hooks/
    │ │ ├── services/
    │ │ ├── types/
    │ │ ├── pages/
    │ │ └── tests/
    │ │
    │ ├── payments/
    │ └── learning/
    │
    ├── components/
    │ ├── Button/
    │ ├── Modal/
    │ ├── DataTable/
    │ └── Form/
    │
    ├── hooks/
    ├── services/
    ├── types/
    ├── utils/
    ├── assets/
    └── main.tsx

    This isn't automatically "better."

    It's better when the application's complexity requires these boundaries.

    Dependency Direction

    Folder structure becomes much more powerful when combined with dependency rules.

    Imagine:

    text
    features/courses/

    depends on:

    text
    components/
    hooks/
    services/
    utils/

    That can be reasonable.

    But if:

    text
    components/Button

    starts importing:

    text
    features/courses/

    you have a problem.

    Why?

    Because a supposedly generic component is now coupled to a business feature.

    A healthier direction is:

    text
    Application
    │
    ▼
    Features
    │
    ├──────► Shared Components
    │
    ├──────► Shared Utilities
    │
    └──────► Infrastructure

    Not:

    text
    Shared Component
    │
    ▼
    Course Feature

    Dependency Graph

    Think of the application as a graph:

    text
    App
    │
    ┌──────┼───────┐
    ▼ ▼ ▼
    Courses Payments Auth
    │
    ├──────────────► Shared Components
    │
    ├──────────────► Shared Hooks
    │
    └──────────────► Utilities

    You want dependencies to be intentional.

    Bad architecture often looks like:

    text
    Courses ─────► Payments
    ▲ │
    │ ▼
    └─────────── Auth

    with circular dependencies.

    Business Boundaries

    Suppose we have:

    text
    features/
    ├── courses/
    ├── payments/
    └── authentication/

    Ask:

    Courses

    Owns:

    text
    Course
    Lesson
    Enrollment
    Progress

    Payments

    Owns:

    text
    Order
    Payment
    Invoice
    Transaction

    Authentication

    Owns:

    text
    Login
    Session
    Token
    User identity

    This is essentially applying domain boundaries to frontend code.

    Don't Share Too Much

    A common enterprise mistake is:

    Let's create one shared utility so everything can use it.

    Soon:

    text
    Feature A
    │
    ▼
    Shared Library
    ▲
    │
    Feature B

    Then the shared library becomes enormous.

    Eventually:

    text
    shared/
    ├── auth
    ├── payments
    ├── courses
    ├── dashboard
    ├── user
    └── everything

    Now nothing is truly independent.

    The principle is:

    Share only what is genuinely generic or intentionally cross-cutting.

    Component Boundaries

    A component should have a meaningful responsibility.

    Good:

    text
    CourseCard
    CourseList
    CourseFilters
    CourseProgress

    Potentially excessive:

    text
    CourseCardTitle
    CourseCardTitleText
    CourseCardTitleWrapper
    CourseCardTitleContainer

    Don't create components merely to reduce the number of lines in a file.

    Create them when they provide:

    text
    Reuse
    Isolation
    Clarity
    Independent behavior
    Testing value

    Co-Location

    Co-location means keeping closely related code together.

    For example:

    text
    features/courses/
    ├── CourseCard.tsx
    ├── CourseCard.test.tsx
    ├── CourseCard.module.css
    └── course.types.ts

    This makes the feature easier to understand.

    Instead of:

    text
    components/
    CourseCard.tsx
    tests/
    CourseCard.test.tsx
    styles/
    CourseCard.css
    types/
    Course.ts

    you can keep related files together when appropriate.

    Tests Near the Code

    Both approaches can work.

    Centralized

    text
    tests/
    └── courses/

    Co-located

    text
    CourseCard/
    ├── CourseCard.tsx
    ├── CourseCard.test.tsx
    └── CourseCard.css

    For feature-heavy applications, co-location often improves discoverability.

    Again, team conventions matter more than a universal rule.

    Barrel Files

    You may see:

    text
    index.ts

    used as a barrel.

    For example:

    tsx
    export { CourseCard } from "./CourseCard";
    export { CourseList } from "./CourseList";

    Then:

    tsx
    import {
    CourseCard,
    CourseList
    } from "@/features/courses";

    This can improve imports.

    But excessive barrel files can also:

    text
    Increase coupling
    Create confusing exports
    Affect dependency analysis
    Create circular dependencies

    Use them intentionally.

    Naming Conventions

    Choose one consistent convention.

    For components:

    text
    CourseCard.tsx
    CourseList.tsx
    CourseDetails.tsx

    For hooks:

    text
    useCourses.ts
    useAuth.ts
    useDebounce.ts

    For services:

    text
    courseService.ts
    authService.ts
    paymentService.ts

    For types:

    text
    course.types.ts
    api.types.ts

    For tests:

    text
    CourseCard.test.tsx

    Consistency matters more than the exact naming convention.

    Example: Complete TechLearningPro Structure

    For the learning platform we are building, a mature structure could look like:

    text
    src/
    │
    ├── app/
    │ ├── App.tsx
    │ ├── routes/
    │ ├── providers/
    │ └── config/
    │
    ├── components/
    │ ├── Button/
    │ ├── Modal/
    │ ├── Card/
    │ ├── DataTable/
    │ └── Loading/
    │
    ├── features/
    │ ├── authentication/
    │ │ ├── components/
    │ │ ├── hooks/
    │ │ ├── services/
    │ │ ├── types/
    │ │ └── pages/
    │ │
    │ ├── courses/
    │ │ ├── components/
    │ │ ├── hooks/
    │ │ ├── services/
    │ │ ├── types/
    │ │ └── pages/
    │ │
    │ ├── learning/
    │ ├── quizzes/
    │ ├── certificates/
    │ ├── payments/
    │ └── profile/
    │
    ├── hooks/
    ├── services/
    ├── types/
    ├── utils/
    ├── assets/
    │
    └── main.tsx

    This gives us a strong foundation for the rest of the course.

    Real-World Request Flow

    Suppose the user opens:

    text
    /courses/react

    The conceptual flow could be:

    text
    Router
    │
    ▼
    CourseDetailsPage
    │
    ▼
    Course Feature
    │
    ├── useCourse()
    │
    ├── courseService
    │
    └── CourseDetails
    │
    ├── CourseHeader
    ├── CourseLessons
    └── CourseProgress

    Shared UI may come from:

    text
    components/
    ├── Button
    ├── Card
    └── Loading

    This gives us clear ownership.

    Real-World Data Flow

    Suppose:

    text
    GET /api/courses/react

    The architecture could look like:

    text
    CourseDetailsPage
    │
    ▼
    useCourse()
    │
    ▼
    courseService
    │
    ▼
    HTTP Client
    │
    ▼
    Spring Boot API
    │
    ▼
    Database

    Then:

    text
    Response
    │
    ▼
    Hook / State
    │
    ▼
    CourseDetails
    │
    ▼
    UI

    This separation keeps API details away from the visual components.

    Common Mistakes

    Mistake 1: One Giant Folder

    text
    src/
    └── components/

    Everything goes there.

    Problem: no business boundaries.

    Mistake 2: One Giant utils.ts

    text
    utils.ts

    contains:

    text
    Date
    Currency
    Auth
    Validation
    API
    Formatting
    Storage

    Problem: unrelated responsibilities become coupled.

    Mistake 3: Global State Everywhere

    text
    GlobalStore

    contains everything.

    Problem: unnecessary coupling and difficult state ownership.

    Mistake 4: Feature Components in Shared Components

    Don't put:

    text
    CourseEnrollmentButton

    into:

    text
    components/

    if it is tightly coupled to course enrollment.

    Prefer:

    text
    features/courses/components/

    Mistake 5: Deep Folder Nesting

    Avoid:

    text
    src/
    features/
    courses/
    components/
    course/
    card/
    container/
    ...

    if it doesn't provide meaningful boundaries.

    How to Decide Where a File Belongs

    Ask these questions.

    Question 1

    Is it generic?

    text
    Yes → Shared components/utilities
    No → Feature

    Question 2

    Does it belong to one business domain?

    text
    Yes → Feature folder
    No → Shared/application layer

    Question 3

    Does it communicate with an external system?

    text
    Yes → Service/infrastructure boundary

    Question 4

    Is it reusable React behavior?

    text
    Yes → Hook

    Question 5

    Is it a route-level screen?

    text
    Yes → Page

    Question 6

    Is it application composition?

    text
    Yes → app/

    This decision process is more valuable than memorizing a folder tree.

    Practical Exercise

    Create this structure:

    text
    src/
    │
    ├── app/
    │ └── App.tsx
    │
    ├── components/
    │ ├── Button.tsx
    │ └── Card.tsx
    │
    ├── features/
    │ └── courses/
    │ ├── components/
    │ │ ├── CourseCard.tsx
    │ │ └── CourseList.tsx
    │ │
    │ ├── hooks/
    │ │ └── useCourses.ts
    │ │
    │ ├── services/
    │ │ └── courseService.ts
    │ │
    │ └── types/
    │ └── course.types.ts
    │
    ├── pages/
    │ └── HomePage.tsx
    │
    ├── hooks/
    ├── services/
    ├── types/
    ├── utils/
    └── main.tsx

    Exercise: Course Domain

    Create:

    tsx
    interface Course {
    id: string;
    title: string;
    level: "Beginner" | "Intermediate" | "Advanced";
    }

    Then:

    tsx
    function CourseCard({
    course
    }: {
    course: Course;
    }) {
    return (
    <article>
    <h2>{course.title}</h2>
    <p>{course.level}</p>
    </article>
    );
    }

    Place the type and component in the appropriate feature folder.

    Ask yourself:

    Why shouldn't CourseCard live inside the generic shared components folder?

    Because it represents a business-specific concept.

    Interview questions & answers

    Interview preparation

    15 questions grouped by difficulty — expand any card for a model answer and follow-up probe.

    Beginner

    4
    1. 1Why is folder structure important in React?
      Beginner

      Model answer

      Folder structure helps organize code according to responsibilities and makes the application easier to navigate and maintain.

      As the application grows, good organization helps developers understand where functionality belongs.

    2. 2What should go inside src?
      Beginner

      Model answer

      Application source code such as components, pages, features, hooks, services, types, utilities, and application assets generally belongs inside src.
    3. 3What is the difference between components and features?
      Beginner

      Model answer

      Shared components generally represent reusable UI building blocks, such as buttons or modals.

      Features represent business capabilities, such as courses, authentication, or payments, and can contain their own components, hooks, services, and types.

    4. 4What is the purpose of the pages folder?
      Beginner

      Model answer

      It typically contains route-level or screen-level components that compose multiple smaller components and represent larger application views.

    Intermediate

    4
    1. 5Should all components go into components/?
      Intermediate

      Model answer

      No. Generic reusable components can go there, but business-specific components should generally remain close to their feature. For example, CourseCard could belong under the courses feature rather than a global shared component directory.
    2. 6Where should a custom hook go?
      Intermediate

      Model answer

      If the hook is generic and reusable across the application, it can go in a shared hooks directory. If it is specific to a business feature, I'd keep it inside that feature.
    3. 7Where should API calls go?
      Intermediate

      Model answer

      I'd generally isolate API communication behind service or data-access boundaries rather than embedding HTTP details throughout components.

      Feature-specific APIs can live inside the relevant feature, while truly shared infrastructure can live in a shared service layer.

    4. 8Should all TypeScript types be placed in types/?
      Intermediate

      Model answer

      No.

      Shared types can live in a common types directory, but feature-specific types should usually remain close to the feature that owns them.

    Advanced

    7
    1. 9How would you structure a large React application?
      Advanced

      Model answer

      I'd prefer a feature-oriented structure where business domains own their components, hooks, services, types, and tests.

      I'd keep generic UI and cross-cutting infrastructure separate.

      I'd also define dependency-direction rules so shared components don't depend on business features.

    2. 10What is more important: folder structure or dependency boundaries?
      Advanced

      Model answer

      Dependency boundaries are more important.

      A beautiful folder structure doesn't help if components have uncontrolled dependencies.

      Folder structure should make those boundaries visible and support them.

    3. 11How do you prevent circular dependencies?
      Advanced

      Model answer

      I'd establish dependency direction and enforce it through architecture rules and tooling where possible.

      Shared layers should not depend on feature layers, and features should avoid directly depending on each other unless that dependency is intentional.

    4. 12How would you organize React code for multiple teams?
      Advanced

      Model answer

      I'd align major feature boundaries with business capabilities and team ownership.

      Each team should have clear ownership of its feature area while shared UI and infrastructure have explicit owners.

      I'd also establish dependency rules to prevent teams from creating hidden coupling.

    5. 13How do you decide between feature-based and layer-based architecture?
      Advanced

      Model answer

      For smaller applications, layer-based organization can be simpler: components/ → hooks/ → services/ → pages/ As business complexity grows, feature-based organization provides better locality: features/ → ├── courses/ → ├── payments/ → └── authentication/ I would start simple and evolve toward feature boundaries when the application and team structure justify them.
    6. 14What is the biggest folder-structure mistake in enterprise React?
      Advanced

      Model answer

      Creating technically organized folders without defining business boundaries. You can have perfectly named components, hooks, and services directories while still having tightly coupled business logic everywhere. The structure should communicate ownership and dependency direction.
    7. 15Would you enforce folder structure through tooling?
      Advanced

      Model answer

      For a large team, yes, where the rules provide real value.

      We can use ESLint import restrictions, dependency rules, code ownership, and architectural tests to prevent forbidden dependencies.

      But I'd avoid enforcing arbitrary folder conventions that don't solve a real problem.

    Architecture Review Example

    Suppose you see:

    text
    src/
    ├── components/
    │ ├── CourseCard.tsx
    │ ├── PaymentForm.tsx
    │ └── UserProfile.tsx
    │
    ├── services/
    │ ├── courseService.ts
    │ ├── paymentService.ts
    │ └── authService.ts
    │
    └── hooks/
    ├── useCourses.ts
    ├── usePayment.ts
    └── useAuth.ts

    A senior engineer should ask:

    Why are all business domains mixed together?

    A potential improvement:

    text
    features/
    ├── courses/
    │ ├── components/
    │ ├── hooks/
    │ ├── services/
    │ └── types/
    │
    ├── payments/
    │ ├── components/
    │ ├── hooks/
    │ ├── services/
    │ └── types/
    │
    └── authentication/
    ├── components/
    ├── hooks/
    ├── services/
    └── types/

    Now ownership becomes clearer.

    The Most Important Principle

    Don't memorize:

    text
    app/
    components/
    features/
    hooks/
    services/
    types/
    utils/

    Instead memorize the questions:

    text
    Who owns this code?
    ↓
    Is it business-specific?
    ↓
    Is it reusable?
    ↓
    Is it application-level?
    ↓
    What is it allowed to depend on?

    Those questions will help you design a structure even when the application doesn't match a textbook example.

    We'll use this as our evolving reference architecture:

    text
    src/
    │
    ├── app/
    │ ├── App.tsx
    │ ├── routes/
    │ ├── providers/
    │ └── config/
    │
    ├── components/
    │ ├── Button/
    │ ├── Card/
    │ ├── Modal/
    │ └── Loading/
    │
    ├── features/
    │ ├── authentication/
    │ ├── courses/
    │ ├── learning/
    │ ├── quizzes/
    │ ├── certificates/
    │ ├── payments/
    │ └── profile/
    │
    ├── hooks/
    ├── services/
    ├── types/
    ├── utils/
    ├── assets/
    │
    └── main.tsx

    As we learn:

    text
    Routing
    State
    Hooks
    API Calls
    Authentication
    Testing
    Performance

    we'll extend this structure rather than randomly adding folders.

    Final Mental Model

    Think of a React application as:

    text
    Application
    │
    ┌────────────────┼────────────────┐
    ▼ ▼ ▼
    App Features Shared
    │ │ │
    │ ┌─────┼─────┐ │
    │ ▼ ▼ ▼ │
    │ Courses Payments Auth │
    │ │ │ │ │
    │ └─────┼─────┘ │
    │ │ │
    └────────────────┼────────────────┘
    ▼
    Shared Components
    Hooks / Utilities
    Infrastructure

    And the dependency direction should generally look like:

    text
    Application
    │
    ▼
    Features
    │
    ├──────────► Shared Components
    ├──────────► Shared Hooks
    ├──────────► Utilities
    └──────────► Infrastructure

    rather than:

    text
    Shared Components
    │
    ▼
    Business Features

    The fundamental principle is:

    Organize React code around ownership, business boundaries, reuse, and dependency direction—not simply around where files happen to fit.

    Next Lesson

    **JSX Basics**

    Now that we understand how a React project is organized, we can start writing React UI.

    We'll cover:

    text
    JSX
    │
    ├── JSX Syntax
    ├── Expressions
    ├── Attributes
    ├── className
    ├── JavaScript inside JSX
    ├── Conditional Rendering
    ├── JSX Rules
    ├── Fragments
    ├── Nested Elements
    ├── JSX vs HTML
    ├── JSX Compilation
    ├── TypeScript + JSX
    └── Common JSX Mistakes

    We'll also connect JSX back to the architecture we've just learned:

    text
    Component
    ↓
    JSX
    ↓
    React Element
    ↓
    React Rendering
    ↓
    Browser UI

    That will be the foundation for everything that follows.

    Ready to mark this lesson complete?Track your journey across the entire course.