<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mostafa Nagedy</title>
    <description>The latest articles on DEV Community by Mostafa Nagedy (@mostafanagedy).</description>
    <link>https://dev.to/mostafanagedy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4214066%2F0776a810-e30b-4ea7-acf3-65febb1f14f0.png</url>
      <title>DEV Community: Mostafa Nagedy</title>
      <link>https://dev.to/mostafanagedy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mostafanagedy"/>
    <language>en</language>
    <item>
      <title>Scalable React Project Structure with Vite and Tailwind CSS</title>
      <dc:creator>Mostafa Nagedy</dc:creator>
      <pubDate>Thu, 29 Oct 2026 01:38:52 +0000</pubDate>
      <link>https://dev.to/mostafanagedy/scalable-react-project-structure-with-vite-and-tailwind-css-371b</link>
      <guid>https://dev.to/mostafanagedy/scalable-react-project-structure-with-vite-and-tailwind-css-371b</guid>
      <description>&lt;h1&gt;
  
  
  Scalable React Project Structure with Vite and Tailwind CSS
&lt;/h1&gt;

&lt;p&gt;Building a React application is easy to start. Keeping it maintainable as it grows is the real challenge.&lt;/p&gt;

&lt;p&gt;As new features are added, a project can quickly become difficult to navigate. Components end up in the wrong folders, API requests are scattered across the codebase, and business logic becomes tightly coupled to the UI.&lt;/p&gt;

&lt;p&gt;A well-organized &lt;strong&gt;React project structure&lt;/strong&gt; helps developers maintain clean code, reuse components, and scale applications without introducing unnecessary complexity.&lt;/p&gt;

&lt;p&gt;In this article, I'll share a practical folder architecture for React applications built with Vite and Tailwind CSS, explain the purpose of each directory, and discuss when to use shared components versus feature-based modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Why Does React Project Structure Matter?
&lt;/h2&gt;

&lt;p&gt;React doesn't enforce a specific folder structure. This flexibility is useful, but it also means developers need to establish conventions that fit their projects.&lt;/p&gt;

&lt;p&gt;Without a clear structure, you may encounter problems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A single &lt;code&gt;components/&lt;/code&gt; folder containing dozens of unrelated files.&lt;/li&gt;
&lt;li&gt;API calls mixed directly into UI components.&lt;/li&gt;
&lt;li&gt;Custom hooks duplicated across different features.&lt;/li&gt;
&lt;li&gt;Business logic scattered throughout the application.&lt;/li&gt;
&lt;li&gt;Difficult refactoring as the codebase grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to create as many folders as possible. It's to make the codebase predictable, easy to navigate, and straightforward to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. A Scalable React Folder Structure
&lt;/h2&gt;

&lt;p&gt;For a medium-sized application, a feature-based architecture is a practical starting point.&lt;/p&gt;

&lt;p&gt;Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── assets/
├── components/
│   ├── ui/
│   │   ├── Button.jsx
│   │   ├── Input.jsx
│   │   └── Modal.jsx
│   └── layout/
│       ├── Navbar.jsx
│       └── Footer.jsx
├── features/
│   ├── auth/
│   │   ├── components/
│   │   ├── hooks/
│   │   └── services/
│   ├── projects/
│   │   ├── components/
│   │   ├── hooks/
│   │   └── services/
│   └── dashboard/
│       ├── components/
│       └── hooks/
├── hooks/
├── services/
│   └── api.js
├── utils/
├── App.jsx
├── main.jsx
└── index.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure separates shared application resources from feature-specific code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; You don't need to create every directory immediately. Start with what your application requires and introduce additional folders when they provide a clear benefit.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Understanding the Main Directories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;components/&lt;/code&gt; — Reusable UI Components
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;components/&lt;/code&gt; directory contains UI elements shared across different parts of the application.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Buttons and input fields.&lt;/li&gt;
&lt;li&gt;Modals and dropdowns.&lt;/li&gt;
&lt;li&gt;Navigation bars and footers.&lt;/li&gt;
&lt;li&gt;Reusable loading and error states.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a generic &lt;code&gt;Button&lt;/code&gt; component can be used in authentication forms, dashboard actions, and project pages without duplicating its implementation.&lt;/p&gt;

&lt;p&gt;A useful rule is to keep shared components independent of specific business features whenever possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;features/&lt;/code&gt; — Feature-Based Modules
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;features/&lt;/code&gt; directory groups related code by functionality rather than by file type.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features/projects/
├── components/
│   ├── ProjectCard.jsx
│   └── ProjectList.jsx
├── hooks/
│   └── useProjects.js
└── services/
    └── projectService.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything related to the projects feature stays together.&lt;/p&gt;

&lt;p&gt;This approach makes it easier to understand a feature, add functionality, and refactor its implementation without searching through unrelated directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;services/&lt;/code&gt; — API Communication
&lt;/h3&gt;

&lt;p&gt;API configuration should be separated from UI components.&lt;/p&gt;

&lt;p&gt;For example, if you're using Axios, you can create a shared API client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/services/api.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_API_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a service dedicated to project-related requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/features/projects/services/projectService.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../services/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProjects&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/projects&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your components can now call the appropriate service instead of handling HTTP configuration themselves.&lt;/p&gt;

&lt;p&gt;This separation also makes API logic easier to test and maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security note:&lt;/strong&gt; Vite exposes variables prefixed with &lt;code&gt;VITE_&lt;/code&gt; to client-side code. Never store private API keys, database credentials, or server-side secrets in these variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;hooks/&lt;/code&gt; — Custom React Hooks
&lt;/h3&gt;

&lt;p&gt;Custom hooks help extract reusable stateful behavior from components.&lt;/p&gt;

&lt;p&gt;Examples include hooks for browser events, media queries, or shared UI behavior.&lt;/p&gt;

&lt;p&gt;Keep hooks used across multiple features in the global &lt;code&gt;hooks/&lt;/code&gt; directory. If a hook belongs exclusively to one feature, place it inside that feature's directory.&lt;/p&gt;

&lt;p&gt;This keeps related functionality close together.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;utils/&lt;/code&gt; — Shared Helper Functions
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;utils/&lt;/code&gt; directory contains general-purpose functions that don't belong to a specific feature.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Date formatting.&lt;/li&gt;
&lt;li&gt;String manipulation.&lt;/li&gt;
&lt;li&gt;Generic data transformations.&lt;/li&gt;
&lt;li&gt;Reusable formatting helpers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid turning this directory into a collection of unrelated business logic. If a utility is specific to a feature, keep it near that feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Shared Components vs. Feature Components
&lt;/h2&gt;

&lt;p&gt;One common architectural question is where a component should live.&lt;/p&gt;

&lt;p&gt;Consider a &lt;code&gt;ProjectCard&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;If it's designed specifically for displaying project information and is only used by the projects feature, keep it inside:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;features/projects/components/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, a generic &lt;code&gt;Button&lt;/code&gt; or &lt;code&gt;Modal&lt;/code&gt; used across unrelated features belongs in the shared &lt;code&gt;components/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;This distinction helps prevent shared components from becoming tightly coupled to application-specific business logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My recommendation:&lt;/strong&gt; Don't move components into a global directory just because they might be reusable someday. Extract them when a genuine reuse case appears.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Where Should State Management Live?
&lt;/h2&gt;

&lt;p&gt;Folder structure and state management should work together.&lt;/p&gt;

&lt;p&gt;A practical approach is to choose state management based on the scope of the state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local state:&lt;/strong&gt; Use &lt;code&gt;useState&lt;/code&gt; or &lt;code&gt;useReducer&lt;/code&gt; for state owned by an individual component.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature state:&lt;/strong&gt; Keep feature-specific state and related logic close to the feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared application state:&lt;/strong&gt; Consider Context or Redux Toolkit when multiple parts of the application need coordinated access to the same state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need Redux just because your application contains several components.&lt;/p&gt;

&lt;p&gt;Start with React's built-in tools and introduce additional state management when the application's requirements justify it.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Organizing Tailwind CSS
&lt;/h2&gt;

&lt;p&gt;Tailwind CSS works naturally with this architecture.&lt;/p&gt;

&lt;p&gt;You can keep utility classes inside component markup and extract repeated UI patterns into reusable components.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
      &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;rounded-lg&lt;/span&gt; &lt;span class="na"&gt;bg-blue-600&lt;/span&gt; &lt;span class="na"&gt;px-4&lt;/span&gt; &lt;span class="na"&gt;py-2&lt;/span&gt;
                 &lt;span class="na"&gt;font-medium&lt;/span&gt; &lt;span class="na"&gt;text-white&lt;/span&gt;
                 &lt;span class="na"&gt;transition&lt;/span&gt; &lt;span class="na"&gt;hover&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;bg-blue-700&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of duplicating the same button styles throughout your application, you can reuse the component and maintain a consistent design.&lt;/p&gt;

&lt;p&gt;For larger projects, consider establishing shared design tokens and consistent component APIs to make the interface easier to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Common Mistakes to Avoid
&lt;/h2&gt;

&lt;p&gt;Even a well-designed folder structure can become difficult to maintain if it's applied without clear principles.&lt;/p&gt;

&lt;p&gt;Here are some mistakes worth avoiding:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Overengineering too early:&lt;/strong&gt; Don't create unnecessary abstractions before you need them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixing unrelated features:&lt;/strong&gt; Keep feature-specific components and services close to their functionality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duplicating API configuration:&lt;/strong&gt; Use a shared API client when appropriate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Putting everything in &lt;code&gt;utils/&lt;/code&gt;:&lt;/strong&gt; Keep business logic close to the feature it belongs to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Making every component global:&lt;/strong&gt; Promote components to shared directories when there is a real reason to do so.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating one structure as universal:&lt;/strong&gt; The right architecture depends on project size, team conventions, and application requirements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A good folder structure should reduce cognitive overhead, not increase it.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Final Thoughts
&lt;/h2&gt;

&lt;p&gt;A scalable React project structure is about clear boundaries and maintainable code, not the number of folders in your repository.&lt;/p&gt;

&lt;p&gt;For smaller applications, a simple structure is often sufficient. As the codebase grows, a feature-based architecture can help organize components, hooks, services, and utilities around real application functionality.&lt;/p&gt;

&lt;p&gt;Start simple, keep related code together, and refactor when your current structure begins to slow down development.&lt;/p&gt;

&lt;p&gt;If you're building React applications, take some time to review your current folder structure. Small organizational improvements can make a significant difference as your project evolves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's Connect
&lt;/h3&gt;

&lt;p&gt;I'm a Full Stack Developer interested in building maintainable web applications and exploring practical software architecture.&lt;/p&gt;

&lt;p&gt;You can explore my portfolio and projects here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio:&lt;/strong&gt; &lt;a href="https://mostafanagedy.vercel.app/" rel="noopener noreferrer"&gt;https://mostafanagedy.vercel.app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/mostafanagedy" rel="noopener noreferrer"&gt;https://github.com/mostafanagedy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/mostafa-nagdey/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/mostafa-nagdey/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What's your preferred approach to organizing React applications: feature-based, type-based, or a combination of both? Share your experience in the comments!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
