Programmer's Picnic
React Lessons by Champak Roy
React File Structure

React File Structure from 0 to Infinity

A React project is not just a pile of files. It is a living system. This lesson explains every important file and folder in a Vite React app, then shows how to grow the project into a clean professional structure.

1. The big picture

React helps us build user interfaces from components. A component is a reusable piece of the screen, such as a header, button, card, menu, form, or page section.

HTML Page
React Starts
Components Load
Data Changes
Screen Updates

In a Vite React project, the browser first opens index.html. That file loads src/main.jsx. Then main.jsx starts React and renders App.jsx inside the page.

Simple idea: index.html is the door. main.jsx is the switch. App.jsx is the first React component. Other folders organize the rest of the app.
index.html src/main.jsx src/App.jsx components pages assets services

2. Starter Vite React structure

After creating a React app using Vite, the starting structure usually looks like this:

react/ ├── node_modules/ Installed packages. Do not edit manually. ├── public/ Static files copied as they are. │ └── vite.svg ├── src/ Main source code of the React app. │ ├── assets/ │ │ └── react.svg │ ├── App.css │ ├── App.jsx │ ├── index.css │ └── main.jsx ├── .gitignore ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── README.md └── vite.config.js
This structure is enough for learning. As your app grows, you should add folders like components, pages, hooks, services, and styles.

3. Root folder files

The root folder is the top-level folder of your React project. In your case, it may be:

D:\react

Important root files

File / Folder Meaning Should beginners edit it?
index.html The HTML entry file used by Vite. Sometimes
package.json Lists commands, dependencies, and project metadata. Carefully
package-lock.json Locks exact installed package versions. No
vite.config.js Configuration file for Vite. Sometimes
.gitignore Tells Git which files not to upload. Sometimes
node_modules Installed packages. Never edit manually
src Your main React source code. Yes
public Static files used directly. Yes

The most important root idea

The root folder is for project-level files. The src folder is for app-level code.

Do not put all components directly in the root folder. Keep React code inside src.

4. Understanding index.html

The index.html file is the first page loaded by the browser. In a Vite React app, it normally contains a root element and a module script.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React App</title>
  </head>

  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

What is root?

The element <div id="root"></div> is the empty box where React places the app.

What is main.jsx doing here?

This line loads the JavaScript module that starts React:

<script type="module" src="/src/main.jsx"></script>
On GitHub Pages, you should not deploy raw source files directly. Vite must build them first. Otherwise the browser may try to load main.jsx directly and show a MIME type error.

5. The public folder

The public folder is for static files that should be copied directly during build.

public/ ├── CNAME Custom domain for GitHub Pages. ├── favicon.svg Browser tab icon. ├── robots.txt Search engine instruction file. ├── site.webmanifest Progressive Web App metadata. └── images/ └── logo.png

When to use public

Use public for Example
Files that must keep their exact name CNAME, robots.txt
Files referenced by full path /images/logo.png
SEO files sitemap.xml, robots.txt
Browser icons favicon.svg

Example: custom domain file

public/CNAME

Content:

react.learnwithchampak.live

How to use a public image

<img src="/images/logo.png" alt="Site logo" />
Public files are not imported into components. They are referred to by path.

6. The src folder

The src folder is the heart of the React app. Most of your actual application code lives here.

src/ ├── main.jsx Starts React. ├── App.jsx Main app component. ├── App.css Styles for App component. ├── index.css Global styles. └── assets/ Images and files imported into JavaScript.

Beginner view

At the beginning, you mainly edit:

  • src/App.jsx
  • src/App.css
  • src/index.css

Professional view

Later, src becomes a well-organized app structure:

src/ ├── assets/ ├── components/ ├── pages/ ├── layouts/ ├── hooks/ ├── services/ ├── data/ ├── utils/ ├── styles/ ├── App.jsx └── main.jsx

7. Understanding main.jsx

main.jsx is the entry point of the React application. It tells React where to place the app.

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

Line-by-line meaning

Line Meaning
import { StrictMode } from 'react' Imports a helper that checks for possible problems during development.
import { createRoot } from 'react-dom/client' Imports the function used to connect React to the browser DOM.
import './index.css' Loads global CSS.
import App from './App.jsx' Imports the main app component.
document.getElementById('root') Finds the root div from index.html.
In most projects, you do not edit main.jsx very often after the first setup.

8. Understanding App.jsx

App.jsx is the first component of your app. It usually controls the main layout.

Simple App.jsx

function App() {
  return (
    <main>
      <h1>Hello React</h1>
      <p>Welcome to Programmer's Picnic.</p>
    </main>
  )
}

export default App

App.jsx with components

import Header from './components/Header.jsx'
import Footer from './components/Footer.jsx'
import HomePage from './pages/HomePage.jsx'

function App() {
  return (
    <>
      <Header />
      <HomePage />
      <Footer />
    </>
  )
}

export default App
The cleaner your App.jsx becomes, the more professional your project structure is becoming.

9. The components folder

Components are reusable pieces of the user interface. Put reusable things inside src/components.

src/components/ ├── Header.jsx ├── Footer.jsx ├── Button.jsx ├── Card.jsx ├── Navbar.jsx └── LessonCard.jsx

Example: Header component

function Header() {
  return (
    <header className="site-header">
      <h1>Programmer's Picnic</h1>
      <p>React lessons by Champak Roy</p>
    </header>
  )
}

export default Header

Example: Card component with props

function LessonCard({ title, description }) {
  return (
    <article className="lesson-card">
      <h2>{title}</h2>
      <p>{description}</p>
    </article>
  )
}

export default LessonCard

Using the component

<LessonCard
  title="React File Structure"
  description="Learn how to organize a React app."
/>
Use components for things that can be reused in many pages.

10. The pages folder

A page is a full screen or major route of your app. Put full pages inside src/pages.

src/pages/ ├── HomePage.jsx ├── AboutPage.jsx ├── CoursesPage.jsx ├── ReactLessonPage.jsx └── NotFoundPage.jsx

Example: HomePage.jsx

function HomePage() {
  return (
    <main>
      <h1>Learn React</h1>
      <p>Start with components, props, state, and file structure.</p>
    </main>
  )
}

export default HomePage

Component vs Page

Component Page
Small reusable part Full route or screen
Button.jsx HomePage.jsx
Used inside pages Uses many components

11. The layouts folder

Layouts are reusable page skeletons. A layout usually contains common structure such as header, navigation, main area, and footer.

src/layouts/ ├── MainLayout.jsx ├── DashboardLayout.jsx └── LessonLayout.jsx

Example: MainLayout.jsx

import Header from '../components/Header.jsx'
import Footer from '../components/Footer.jsx'

function MainLayout({ children }) {
  return (
    <>
      <Header />
      <main>{children}</main>
      <Footer />
    </>
  )
}

export default MainLayout

Using a layout

import MainLayout from '../layouts/MainLayout.jsx'

function HomePage() {
  return (
    <MainLayout>
      <h1>Home</h1>
      <p>Welcome to the React course.</p>
    </MainLayout>
  )
}

export default HomePage

12. The hooks folder

Hooks are functions that let components use React features such as state and effects. Custom hooks help you reuse logic.

src/hooks/ ├── useLocalStorage.js ├── useWindowSize.js ├── useFetch.js └── useTheme.js

Example: useLocalStorage.js

import { useEffect, useState } from 'react'

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const saved = localStorage.getItem(key)
    return saved ? JSON.parse(saved) : initialValue
  })

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value))
  }, [key, value])

  return [value, setValue]
}

export default useLocalStorage

Using the hook

import useLocalStorage from '../hooks/useLocalStorage.js'

function ThemeSwitcher() {
  const [theme, setTheme] = useLocalStorage('theme', 'light')

  return (
    <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      Current theme: {theme}
    </button>
  )
}
Custom hook file names usually start with use, such as useFetch.js or useTheme.js.

13. The services folder

The services folder is for code that talks to external systems: Application Programming Interfaces, databases, authentication servers, or local storage services.

src/services/ ├── api.js ├── lessonService.js ├── authService.js └── storageService.js

Example: api.js

const API_BASE_URL = 'https://example.com/api'

export async function getLessons() {
  const response = await fetch(`${API_BASE_URL}/lessons`)

  if (!response.ok) {
    throw new Error('Could not load lessons')
  }

  return response.json()
}

Using a service

import { getLessons } from '../services/api.js'

async function loadLessons() {
  try {
    const lessons = await getLessons()
    console.log(lessons)
  } catch (error) {
    console.error(error.message)
  }
}
Keep network and data-fetching code away from visual components when possible. This makes your components cleaner.

14. The assets folder

Use src/assets for images and files that you want to import inside JavaScript or JSX.

src/assets/ ├── images/ │ ├── hero.png │ └── react-logo.svg ├── icons/ │ └── menu.svg └── data/ └── lessons.json

Importing an image

import heroImage from '../assets/images/hero.png'

function Hero() {
  return (
    <section>
      <img src={heroImage} alt="React lesson illustration" />
      <h1>Learn React</h1>
    </section>
  )
}

export default Hero

public vs src/assets

Question Use public Use src/assets
Need exact filename? Yes No
Want to import in JSX? No Yes
Example /images/logo.png import logo from './assets/logo.png'

15. Styling files

Styling can be organized in many ways. Beginners usually start with App.css and index.css.

src/styles/ ├── global.css ├── variables.css ├── layout.css ├── buttons.css └── utilities.css

Beginner structure

src/
├── App.css
└── index.css

Better structure

src/
├── styles/
│   ├── global.css
│   ├── variables.css
│   └── utilities.css
└── components/
    └── Button.jsx

Example: variables.css

:root {
  --brand: #0b67b2;
  --text: #172033;
  --background: #f7fbff;
}

Example: importing styles in main.jsx

import './styles/global.css'
import './styles/variables.css'
import App from './App.jsx'

16. Routing files

Routing means showing different pages for different URLs, such as:

/           → Home page
/about      → About page
/courses    → Courses page
/contact    → Contact page

For small apps, routes can stay inside App.jsx. For larger apps, create a separate routes file.

src/routes/ └── AppRoutes.jsx

Possible AppRoutes.jsx

import HomePage from '../pages/HomePage.jsx'
import AboutPage from '../pages/AboutPage.jsx'
import NotFoundPage from '../pages/NotFoundPage.jsx'

function AppRoutes() {
  const path = window.location.pathname

  if (path === '/') return <HomePage />
  if (path === '/about') return <AboutPage />

  return <NotFoundPage />
}

export default AppRoutes
For serious routing, many projects use a routing library. But this lesson focuses on file structure, so the main idea is to keep route-related code in a predictable place.

17. data and utils folders

data folder

Use data for local JSON-like information used by your app.

src/data/
├── lessons.js
├── menuItems.js
└── faqs.js

utils folder

Use utils for small helper functions.

src/utils/
├── formatDate.js
├── slugify.js
└── validateEmail.js

Example: data file

export const lessons = [
  {
    id: 1,
    title: 'React File Structure',
    level: 'Beginner'
  },
  {
    id: 2,
    title: 'React Components',
    level: 'Beginner'
  }
]

Example: utility function

export function slugify(text) {
  return text
    .toLowerCase()
    .trim()
    .replaceAll(' ', '-')
}

18. Environment files

Environment files store configuration values that may change between local development and production.

.env .env.local .env.production

Example .env file

VITE_SITE_NAME=Programmer's Picnic
VITE_API_URL=https://example.com/api

Using environment variables

const siteName = import.meta.env.VITE_SITE_NAME
const apiUrl = import.meta.env.VITE_API_URL
In Vite, browser-exposed custom environment variables should start with VITE_. Do not put private passwords or secret keys in frontend environment files.

19. GitHub Pages deployment files

For your React site on GitHub Pages, these files are important:

react/ ├── public/ │ └── CNAME ├── .github/ │ └── workflows/ │ └── deploy.yml └── vite.config.js

public/CNAME

react.learnwithchampak.live

vite.config.js for custom domain

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  base: '/',
})

.github/workflows/deploy.yml

name: Deploy React site to GitHub Pages

on:
  push:
    branches:
      - main

  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: github-pages
  cancel-in-progress: false

jobs:
  build:
    name: Build React app
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Build with Vite
        run: npm run build

      - name: Upload dist folder
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./dist

  deploy:
    name: Deploy to GitHub Pages
    needs: build
    runs-on: ubuntu-latest

    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

    steps:
      - name: Deploy site
        id: deployment
        uses: actions/deploy-pages@v4
GitHub Pages should use GitHub Actions as the source. Do not use Deploy from branch → main / root for a Vite React app.

20. Professional React file structure

A professional React structure separates responsibilities. Components stay with components, pages stay with pages, data logic stays with services, and helper functions stay with utilities.

react/ ├── .github/ │ └── workflows/ │ └── deploy.yml ├── public/ │ ├── CNAME │ ├── favicon.svg │ ├── robots.txt │ └── sitemap.xml ├── src/ │ ├── assets/ │ │ ├── images/ │ │ └── icons/ │ ├── components/ │ │ ├── Header.jsx │ │ ├── Footer.jsx │ │ ├── Button.jsx │ │ └── LessonCard.jsx │ ├── pages/ │ │ ├── HomePage.jsx │ │ ├── AboutPage.jsx │ │ ├── CoursesPage.jsx │ │ └── NotFoundPage.jsx │ ├── layouts/ │ │ └── MainLayout.jsx │ ├── hooks/ │ │ ├── useFetch.js │ │ └── useLocalStorage.js │ ├── services/ │ │ └── api.js │ ├── data/ │ │ └── lessons.js │ ├── utils/ │ │ └── slugify.js │ ├── styles/ │ │ ├── global.css │ │ └── variables.css │ ├── App.jsx │ └── main.jsx ├── .gitignore ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── README.md └── vite.config.js

Why this is better

Folder Responsibility
components Reusable user interface parts.
pages Full screens or route-level views.
layouts Common page skeletons.
hooks Reusable React logic.
services Application Programming Interface and external communication.
utils Small helper functions.
data Local app data.
styles Global styling system.

21. Naming rules

Component files

Use PascalCase for component file names:

Header.jsx
Footer.jsx
LessonCard.jsx
CourseList.jsx

Hook files

Start custom hook names with use:

useFetch.js
useTheme.js
useLocalStorage.js

Utility files

Use camelCase for helper files:

formatDate.js
slugify.js
validateEmail.js

Page files

Use clear page names:

HomePage.jsx
AboutPage.jsx
ContactPage.jsx
NotFoundPage.jsx
Good names reduce confusion. A developer should understand a file's role before opening it.

22. Practical rules for organizing React files

Do this

  • Keep reusable user interface pieces in components.
  • Keep full screens in pages.
  • Keep external calls in services.
  • Keep reusable logic in hooks.
  • Keep helpers in utils.
  • Use clear file names.

Avoid this

  • Putting everything inside App.jsx.
  • Putting all files directly inside src.
  • Editing node_modules.
  • Uploading node_modules to GitHub.
  • Putting secret passwords in frontend files.
  • Mixing visual components with data-fetching code.

The one-sentence rule

A file should have one clear job. A folder should group files with similar jobs.

23. How a React project grows

Level 0: First day

src/
├── App.jsx
├── App.css
├── index.css
└── main.jsx

Level 1: Few components

src/
├── components/
│   ├── Header.jsx
│   ├── Footer.jsx
│   └── Card.jsx
├── App.jsx
└── main.jsx

Level 2: Multiple pages

src/
├── components/
├── pages/
│   ├── HomePage.jsx
│   ├── AboutPage.jsx
│   └── CoursesPage.jsx
├── App.jsx
└── main.jsx

Level 3: Real app

src/
├── assets/
├── components/
├── pages/
├── layouts/
├── hooks/
├── services/
├── data/
├── utils/
├── styles/
├── App.jsx
└── main.jsx

Level infinity: Feature-based structure

Very large apps may organize by feature:

src/
├── features/
│   ├── auth/
│   │   ├── LoginPage.jsx
│   │   ├── authService.js
│   │   └── useAuth.js
│   ├── courses/
│   │   ├── CoursesPage.jsx
│   │   ├── CourseCard.jsx
│   │   └── courseService.js
│   └── dashboard/
│       ├── DashboardPage.jsx
│       └── DashboardStats.jsx
├── shared/
│   ├── components/
│   ├── hooks/
│   └── utils/
├── App.jsx
└── main.jsx
Do not start with a huge structure on day one. Grow the structure as the app grows.

24. Useful commands

Create app

npm create vite@latest react

Go inside app

cd react

Install packages

npm install

Run locally

npm run dev

Build for production

npm run build

Preview production build

npm run preview

Create useful folders

mkdir src\components src\pages src\layouts src\hooks src\services src\data src\utils src\styles

Git commands

git add .
git commit -m "Organize React file structure"
git push

25. Mini project: organize the starter app

Let us convert a starter React app into a cleaner structure.

Step 1: Create folders

mkdir src\components src\pages src\layouts src\styles

Step 2: Create Header.jsx

function Header() {
  return (
    <header className="site-header">
      <h1>Programmer's Picnic</h1>
      <p>React file structure lesson</p>
    </header>
  )
}

export default Header

Step 3: Create Footer.jsx

function Footer() {
  return (
    <footer className="site-footer">
      <p>Created by Champak Roy</p>
    </footer>
  )
}

export default Footer

Step 4: Create HomePage.jsx

function HomePage() {
  return (
    <section className="home-page">
      <h2>Learn React File Structure</h2>
      <p>Start small. Organize as the app grows.</p>
    </section>
  )
}

export default HomePage

Step 5: Update App.jsx

import Header from './components/Header.jsx'
import Footer from './components/Footer.jsx'
import HomePage from './pages/HomePage.jsx'

function App() {
  return (
    <>
      <Header />
      <HomePage />
      <Footer />
    </>
  )
}

export default App
Now the app is already more organized than the default starter app.

26. Practice quiz

1. Which file starts the React app?

src/main.jsx

2. Which file contains the root div?

index.html

3. Where should reusable UI pieces go?

src/components

4. Where should full screens go?

src/pages

5. Where should custom hooks go?

src/hooks

6. Where should API calls go?

src/services

7. Should you edit node_modules manually?

No. node_modules is generated by npm.

8. What is the purpose of public/CNAME?

It stores the custom domain for GitHub Pages.

9. What should GitHub Pages deploy for a Vite React app?

The built dist output through GitHub Actions.

27. Final checklist

Item Correct place
Main HTML entry index.html
React entry src/main.jsx
Main app component src/App.jsx
Reusable UI src/components
Pages src/pages
Layouts src/layouts
Reusable React logic src/hooks
API calls src/services
Helper functions src/utils
Imported images src/assets
Static public files public
Custom domain public/CNAME
GitHub Actions deployment .github/workflows/deploy.yml
If you understand this checklist, you understand the skeleton of a professional React app.