Beyond the Basics: Structuring React Apps That Scale

Anurag VahistAnurag Vahist
3 min read

When you're working on a small React app, throwing everything into a components folder may work just fine. But as your project grows β€” with more pages, features, and contributors β€” having a well-structured architecture becomes critical.

In this post, I’ll walk through how I structure large React applications based on real-world experience. This structure helps improve scalability, maintainability, and developer onboarding.


πŸ“ Folder Structure

Here’s my typical top-level folder structure:

src/
  β”œβ”€β”€ components/         # Reusable UI components (buttons, modals, etc.)
  β”œβ”€β”€ features/           # Feature-specific modules (per route or domain)
  β”œβ”€β”€ pages/              # Route-based components (e.g., for React Router)
  β”œβ”€β”€ hooks/              # Custom reusable hooks (global, not feature-specific)
  β”œβ”€β”€ contexts/           # React context definitions & providers
  β”œβ”€β”€ services/           # API calls, SDK wrappers, integrations
  β”œβ”€β”€ utils/              # Helper functions and pure utilities
  β”œβ”€β”€ constants/          # Static config, enums, roles, routes
  β”œβ”€β”€ assets/             # Images, icons, fonts
  └── types/              # TypeScript types and interfaces

Let’s break some of these down.


πŸ’‘ components/ vs features/

  • components/: Reusable, stateless UI pieces like Button, Modal, Table, etc.

  • features/: Isolated feature logic that may include components, hooks, and even state.

Example features/ structure:

features/
  └── user/
      β”œβ”€β”€ components/       # Feature-specific UI
      β”œβ”€β”€ hooks/            # Feature-specific hooks
      β”œβ”€β”€ services.ts       # API calls for user feature
      β”œβ”€β”€ UserPage.tsx
      └── index.ts

This keeps features modular and avoids one massive components/ folder.


πŸ” Reusable Hooks (hooks/)

Global hooks that are reused across the app go here. For example:

  • useDebounce

  • useOutsideClick

  • useAuth

  • useQueryParams

Each hook is isolated in its own file with relevant tests and types.


🌐 Global State: Context API vs Redux

  • I prefer Context API + custom hooks for managing local/global app state.

  • Redux or Zustand is introduced only when state becomes complex or needs cross-feature syncing.

  • Example of lightweight context:

// contexts/AuthContext.tsx
const AuthContext = createContext(null);
export const AuthProvider = ({ children }) => { /*...*/ };
export const useAuth = () => useContext(AuthContext);

πŸ›° API Calls (services/)

I keep all API-related logic here, often using Axios or React Query.

Structure example:

services/
  β”œβ”€β”€ http.ts            # Axios instance
  β”œβ”€β”€ userService.ts     # Functions like getUser, updateUser
  └── authService.ts

This keeps the UI clean and separates concerns.


βš™οΈ Constants and Config

Use constants/ to store:

  • Routes

  • Roles/permissions

  • Default values

  • App-wide enums or flags

Example:

// constants/routes.ts
export const ROUTES = {
  HOME: '/',
  LOGIN: '/login',
  DASHBOARD: '/dashboard',
};

βœ… Why This Works

  • Scalability: New features can be added without cluttering the root or unrelated areas.

  • Separation of concerns: UI, logic, and API are cleanly split.

  • Easier onboarding: New devs can find things faster.

  • Testability: Isolated logic and components make testing easier.


🧩 Bonus: Tech Stack Tips

  • React Query for data fetching and caching

  • React Hook Form + Yup/Zod for forms and validation

  • Zustand or Jotai for local state (if Context gets messy)

  • TypeScript for type safety (essential on large teams)


πŸš€ Final Thoughts

There’s no one-size-fits-all solution, but a consistent structure helps your team stay productive and sane as the codebase grows. Start simple, and evolve the structure as complexity increases.

Let me know how you structure your apps β€” always open to learn better ways!


Thanks for reading!

πŸ‘‰ Follow me for more frontend insights, especially around React, architecture, and performance.

0
Subscribe to my newsletter

Read articles from Anurag Vahist directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anurag Vahist
Anurag Vahist