React Project Setup
React Project Setup explains modern React and TypeScript project organization with Vite, package configuration, source and public assets, environment variables, feature boundaries, Git, quality tooling, CI/CD, and enterprise architecture.
Learning Objectives
By the end of this lesson, you will be able to:
- Understand what a React project setup actually contains.
- Create a modern React + TypeScript project.
- Understand the role of Node.js, npm, and the package manager.
- Understand the role of Vite in a React project.
- Understand the project directory structure.
- Understand
package.jsonand lockfiles. - Understand
src,public, and the application entry point. - Understand
main.tsx,App.tsx, andindex.html. - Understand development and production scripts.
- Configure environment variables safely.
- Understand basic Git setup for a React project.
- Establish a professional project structure suitable for scaling.
- Understand common project-setup mistakes.
- Troubleshoot common setup problems.
- Explain React project setup from a senior-engineering perspective.
Introduction
In the previous lesson, we installed React.
Now we need to go one level deeper.
Installing React gives us the library.
Project setup gives us the environment in which the application will be developed, tested, built, and eventually deployed.
Think about a React application like this:
React Application│┌──────────────────┼──────────────────┐▼ ▼ ▼Source Code Tooling Configuration│ │ │▼ ▼ ▼Components Vite TypeScriptHooks npm ESLintServices Build TestingPages Dev Server Environment│ │ │└──────────────────┼──────────────────┘▼Production
A professional React developer should understand all three areas.
What Is React Project Setup?
A React project setup defines:
Project│├── Application source├── Dependencies├── Build configuration├── Development server├── TypeScript configuration├── Environment configuration├── Testing├── Code quality└── Deployment configuration
For a simple learning project, this may be relatively small.
For an enterprise application, it can become much more sophisticated.
Recommended Setup for This Course
For this course, we'll use:
React+TypeScript+Vite+npm+VS Code+Modern Browser
The basic architecture is:
Developer│▼VS Code│▼React + TypeScript│▼Vite│▼Browser
For learning React fundamentals, this gives us a relatively clean environment.
For a production application, you should evaluate whether a React framework is more appropriate.
Create the Project
Open your terminal.
Run:
npm create vite@latest techlearningpro-react -- --template react-ts
This creates:
techlearningpro-react/
Now enter the directory:
cd techlearningpro-react
Install dependencies:
npm install
Start the development server:
npm run dev
You should see a local URL in the terminal, commonly:
http://localhost:5173
The exact port can vary.
What Did We Just Create?
The generated project will contain files similar to:
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 change between tool versions.
Don't memorize the filenames.
Understand their responsibilities.
The Big Picture
The most useful mental model is:
React Project│┌─────────────────┼──────────────────┐▼ ▼ ▼Runtime Source Tooling│ │ │▼ ▼ ▼Browser src/ Vite│ │ ││ ┌────┼────┐ ││ ▼ ▼ ▼ ││ App Components Hooks ││ │ │└─────────────────┼──────────────────┘▼Build│▼Production
package.json
One of the most important files is:
package.json
It describes the project.
A simplified example:
{"name": "techlearningpro-react","version": "0.0.0","private": true,"scripts": {"dev": "vite","build": "tsc -b && vite build","lint": "eslint .","preview": "vite preview"},"dependencies": {"react": "...","react-dom": "..."},"devDependencies": {"typescript": "...","vite": "..."}}
The exact versions depend on when the project is created.
Why package.json Matters
It tells the development environment:
What is this project?│├── What packages does it need?│├── What scripts can I run?│├── What tools are required?│└── What version constraints exist?
For example:
npm run dev
looks at:
"scripts": {"dev": "vite"}
and executes the associated command.
Dependencies vs DevDependencies
You will commonly see:
"dependencies": {}
and:
"devDependencies": {}
Dependencies
Packages needed by the application/runtime model.
Examples:
reactreact-dom
DevDependencies
Packages primarily used during development/building/testing.
Examples:
vitetypescripteslinttesting tools
The exact classification can vary based on tooling and deployment strategy, but this distinction is important for project management.
package-lock.json
When you run:
npm install
npm creates or updates:
package-lock.json
This records the resolved dependency tree.
Conceptually:
package.json│▼Version ranges│▼Dependency Resolution│▼package-lock.json│▼Exact dependency tree
This helps different environments install compatible versions.
For application repositories, the lockfile should normally be committed to source control.
node_modules
After installation:
node_modules/
appears.
It contains installed packages.
Conceptually:
node_modules/│├── react├── react-dom├── vite├── typescript├── eslint└── dependencies...
It can become very large.
You generally do not commit it to Git.
Instead:
Git Repository│├── package.json├── package-lock.json└─ ─ src/
Then another developer can run:
npm install
.gitignore
A React project should have a .gitignore.
Typical entries include:
node_modules/dist/.env.env.local
The purpose is to prevent generated files and sensitive local configuration from being committed.
For example:
node_modules↓Generated dependency directory↓Do not commit
The src Directory
The most important application directory is generally:
src/
This is where your application source code lives.
Initially:
src/│├── App.tsx├── main.tsx├── App.css├── index.css└── assets/
As the application grows, we'll organize it more deliberately.
For example:
src/│├── components/├── features/├── pages/├── hooks/├── services/├── types/├── utils/├── assets/├── App.tsx└── main.tsx
main.tsx
This is commonly the entry point of a Vite React application.
A simplified version:
import { StrictMode } from "react";import { createRoot } from "react-dom/client";import App from "./App";createRoot(document.getElementById("root")!).render(<StrictMode><App /></StrictMode>);
This file connects:
Browser DOM│▼React│▼App
index.html
At the root of the project you'll find:
index.html
A simplified version contains:
<!doctype html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport"content="width=device-width, initial-scale=1.0" /><title>TechLearningPro</title></head><body><div id="root"></div><scripttype="module"src="/src/main.tsx"></script></body></html>
The important element is:
<div id="root"></div>
React uses this element as the mounting point.
Complete Startup Flow
Now connect everything.
Browser│▼index.html│▼<div id="root">│▼main.tsx│▼createRoot()│▼<App />│▼Component Tree│▼React Rendering│▼Browser UI
This is one of the most important diagrams to remember.
App.tsx
App.tsx commonly acts as the root component.
Example:
function App() {return (<main><h1>Welcome to TechLearningPro</h1><p>Learn React step by step.</p></main>);}export default App;
Eventually, App should not become a giant component.
Instead:
App│├── Header├── Navigation├── Main│ ├── Hero│ ├── CourseList│ └── LearningStats└── Footer
public Directory
You may also have:
public/
This directory is useful for assets that need to be served as static files without being processed through the normal source module pipeline.
For example:
public/├── favicon.ico├── robots.txt└── static-assets/
Use it intentionally.
Don't automatically place every image in public.
For many application assets, importing them from src is preferable because the build tool can process and reference them appropriately.
src/assets
Vite projects often include:
src/assets/
This can contain assets imported by application code:
import logo from "./assets/logo.svg";
Then:
<img src={logo} alt="TechLearningPro" />
This allows the build system to understand the asset as part of the application dependency graph.
vite.config.ts
This file configures Vite.
A simplified example might look like:
import { defineConfig } from "vite";import react from "@vitejs/plugin-react";export default defineConfig({plugins: [react()]});
The configuration can later include things such as:
AliasesProxyPluginsBuild configurationServer settings
For example, you may eventually want:
@/↓src/
instead of:
../../../../components
Why Aliases Matter
Imagine:
import Button from "../../../../components/Button";
This becomes difficult to read.
An alias can allow:
import Button from "@/components/Button";
Conceptually:
@/↓src/
Then:
@/components@/features@/services@/hooks
become easier to manage.
However, aliases should be introduced consistently across TypeScript and build tooling.
TypeScript Configuration
A modern Vite React TypeScript project may contain several TypeScript configuration files.
For example:
tsconfig.jsontsconfig.app.jsontsconfig.node.json
These separate TypeScript concerns between:
ApplicationNode-based toolingProject references/configuration
You don't need to memorize every setting initially.
Understand the purpose:
TypeScript configuration tells the compiler how your project's TypeScript code should be understood and checked.
Why TypeScript?
Consider:
function CourseCard({course}) {return (<h2>{course.title}</h2>);}
What exactly is course?
TypeScript allows:
interface Course {id: string;title: string;duration: number;}function CourseCard({course}: {course: Course;}) {return (<h2>{course.title}</h2>);}
Now the component has an explicit contract.
This becomes extremely valuable in larger applications.
Scripts
Run:
npm run
You can see the available scripts.
A typical Vite project includes scripts similar to:
devbuildlintpreview
Development
npm run dev
Production build
npm run build
Linting
npm run lint
Preview production build
npm run preview
The exact scripts depend on the generated project and your configuration.
Development Lifecycle
When you execute:
npm run dev
the flow is:
Terminal│▼npm│▼Vite│▼Development Server│▼Browser
When you edit:
App.tsx
the development tooling detects the change and updates the browser.
This is the development feedback loop:
Write Code│▼Save│▼Vite detects change│▼React refresh│▼Browser updates
Production Lifecycle
Production is different.
You run:
npm run build
Conceptually:
Source│▼TypeScript / JSX│▼Build Tool│├── Optimize├── Transform├── Bundle└── Generate assets│▼dist/
Then the resulting assets are deployed.
Environment Variables
Real applications often need environment-specific configuration.
For example:
Development APIProduction APIAnalytics configurationFeature flags
With Vite, client-exposed environment variables commonly use the VITE_ prefix.
For example:
.env.development
could contain:
VITE_API_BASE_URL=https://dev-api.example.com
And production:
.env.production
could contain:
VITE_API_BASE_URL=https://api.example.com
Then:
const apiUrl = import.meta.env.VITE_API_BASE_URL;
Important Security Warning
This is extremely important.
Anything exposed to browser-side React code should be treated as public.
Do not put:
Database passwordPrivate API secretJWT signing keyCloud secretPayment secret
into:
VITE_SECRET_KEY
or any other client-side environment variable expecting it to remain secret.
The browser must receive the value.
Therefore:
Frontend environment variable↓Browser↓NOT a secret
Secrets belong on trusted server-side infrastructure.
Feature-Based Project Structure
As the application grows, avoid putting everything into:
src/components/
A large enterprise application might use:
src/│├── app/│ ├── router/│ ├── providers/│ └── store/│├── features/│ ├── authentication/│ ├── courses/│ ├── learning/│ ├── payments/│ └── profile/│├── components/│ ├── Button/│ ├── Modal/│ └── DataTable/│├── services/├── hooks/├── types/├── utils/├── assets/│├── App.tsx└── main.tsx
This is much closer to how a large application can be organized.
Feature vs Shared Component
This distinction is extremely important.
Suppose we have:
CourseCard
which is specific to the course domain.
It belongs naturally under:
features/courses/
But:
ButtonModalTooltipInput
might belong to:
components/
because they are generic UI building blocks.
Think:
Feature↓Business/domain-specificShared component↓Generic/reusable
Recommended Enterprise Structure
A more mature structure could look like:
src/│├── app/│ ├── App.tsx│ ├── routes/│ ├── providers/│ └── config/│├── features/│ ├── auth/│ │ ├── components/│ │ ├── hooks/│ │ ├── services/│ │ ├── types/│ │ └── pages/│ ││ ├── courses/│ │ ├── components/│ │ ├── hooks/│ │ ├── services/│ │ ├── types/│ │ └── pages/│ ││ └── learning/│ ├── components/│ ├── hooks/│ ├── services/│ └── pages/│├── components/├── hooks/├── services/├── types/├── utils/└── assets/
This isn't a mandatory structure.
The important principle is:
Organize around business boundaries rather than blindly organizing around file types.
Application Boundaries
Imagine:
features/├── courses/├── payments/└── authentication/
You don't want:
Payments↓random dependency↓Courses↓Authentication↓Payments
creating circular business dependencies.
Instead:
Authentication│▼Application│┌─────┼──────┐▼ ▼ ▼Courses Payments Learning
Clear boundaries make large systems easier to evolve.
React Providers
As applications become more complex, the root may contain providers:
function App() {return (<AuthProvider><ThemeProvider><RouterProvider /></ThemeProvider></AuthProvider>);}
Conceptually:
App│└── AuthProvider│└── ThemeProvider│└── Router│└── Pages
We'll study these concepts later.
Don't add providers simply because a library provides one.
Every global provider introduces another architectural dependency.
Git Setup
Initialize Git if necessary:
git init
Then:
git add .git commit -m "Initial React project setup"
A good repository should contain:
src/package.jsonpackage-lock.jsonREADME.md.gitignoreconfiguration files
It should generally not contain:
node_modules/dist/local secrets
README
Even a learning project should have:
README.md
For example:
# TechLearningPro ReactReact + TypeScript learning project.## Requirements- Node.js- npm## Installationnpm install## Developmentnpm run dev## Production Buildnpm run build
For enterprise applications, the README should become much more comprehensive.
Enterprise README
A professional project README might contain:
Project OverviewArchitecturePrerequisitesInstallationEnvironment SetupDevelopmentTestingBuildDeploymentTroubleshootingContribution GuidelinesBranching StrategySecurityContacts
This reduces onboarding time.
Linting
Linting catches common code-quality problems.
For example:
Unused variablesInvalid patternsPotential bugsInconsistent codeReact-specific issues
A typical project may use ESLint.
Run:
npm run lint
The exact rules should be agreed upon by the team.
Formatting
Teams often use an automated formatter such as Prettier.
Instead of developers debating:
spaces vs tabssingle vs double quotesline lengthsemicolon rules
the formatter makes the decision automatically.
This is important:
Code formatting should be automated, not debated during code review.
Testing Setup
A production React project should eventually have multiple levels of testing.
Testing│├── Unit├── Component├── Integration└── End-to-End
For example:
Component│▼User Interaction│▼Expected UI
We'll cover testing in a dedicated section later.
Common Project Setup Mistakes
Mistake 1: One giant App.tsx
Avoid:
App.tsx└── 3,000 lines
Prefer meaningful boundaries.
Mistake 2: Everything in components/
Avoid:
components/├── Course├── Payment├── Auth├── Dashboard├── Button├── Modal└── EverythingElse
Separate domain-specific features from generic components.
Mistake 3: Global state for everything
Not every value belongs in global state.
Ask:
Who actually needs this data?
Mistake 4: Secrets in .env
.env does not automatically make browser-exposed secrets secure.
Mistake 5: Committing node_modules
Don't.
Mistake 6: No lockfile
For application repositories, the dependency lockfile is normally part of source control.
Mistake 7: Too many dependencies
Every dependency adds:
MaintenanceSecurityUpgradeBundleCompatibility
cost.
Mistake 8: Overengineering on day one
Don't create:
50 folders20 abstractions15 providers
before the application needs them.
Practical Setup Exercise
Create:
techlearningpro-react/
Then organize:
src/│├── components/│ └── Header.tsx│├── features/│ └── courses/│ └── CourseCard.tsx│├── pages/│ └── HomePage.tsx│├── App.tsx└── main.tsx
Header.tsx
export function Header() {return (<header><h1>TechLearningPro</h1></header>);}
CourseCard.tsx
interface CourseCardProps {title: string;level: string;}export function CourseCard({title,level}: CourseCardProps) {return (<article><h2>{title}</h2><p>{level}</p></article>);}
HomePage.tsx
import { CourseCard } from "../features/courses/CourseCard";export function HomePage() {return (<main><h2>Featured Courses</h2><CourseCardtitle="React Mastery"level="Advanced"/><CourseCardtitle="Spring Boot"level="Advanced"/></main>);}
Update App.tsx
import { Header } from "./components/Header";import { HomePage } from "./pages/HomePage";function App() {return (<><Header /><HomePage /></>);}export default App;
Now the architecture is:
App│├── Header│└── HomePage│├── CourseCard└── CourseCard
What You Should Learn From This Exercise
Don't focus only on creating folders.
Understand the dependency direction:
App│▼Page│▼Feature│▼Component
For example:
App↓HomePage↓courses↓CourseCard
The goal is to make dependencies understandable.
Interview questions & answers
Interview preparation
15 questions grouped by difficulty — expand any card for a model answer and follow-up probe.
Beginner
1What is a React project?
BeginnerModel answer
A React project is an application codebase that uses React along with the required development and build tooling.
It normally contains source code, dependency configuration, build configuration, and scripts for development, testing, and production builds.
2What is package.json?
BeginnerModel answer
package.jsonis the main project metadata and dependency configuration file in a Node-based JavaScript project. It contains information such as project scripts, dependencies, and development dependencies.3What is node_modules?
BeginnerModel answer
It's the directory where npm installs the project's dependencies.
We normally don't commit it to Git because it can be recreated from the package configuration and lockfile.
4What is main.tsx?
BeginnerModel answer
In a typical Vite React TypeScript application,main.tsxis the entry point that creates the React root and renders the application's root component into the DOM.
Intermediate
5What is the purpose of index.html?
IntermediateModel answer
It provides the initial HTML document loaded by the browser. It contains the DOM element where the React application is mounted, typically something like<div id="root"></div>.6Why do we need Vite?
IntermediateModel answer
Vite provides development and build tooling.
It gives us a development server, fast development feedback, and production build capabilities.
React itself doesn't provide all of those application development tools.
7What is the difference between src and public?
IntermediateModel answer
srcgenerally contains application source code and assets that participate in the module/build system.publicis intended for static assets that need to be served directly. The exact usage should be based on the build tool's conventions.8Why should we commit package-lock.json?
IntermediateModel answer
It records the resolved dependency tree and helps make installations more reproducible across developer machines and CI environments.
Advanced
9How would you structure a large React project?
AdvancedModel answer
I'd generally organize around business or feature boundaries, with shared components and infrastructure separated from domain-specific code.
For example, authentication, courses, payments, and learning could each have their own feature boundaries.
I'd avoid blindly organizing everything by technical file type.
10How do you prevent a React project from becoming difficult to maintain?
AdvancedModel answer
I'd establish clear component and feature boundaries, control dependency direction, keep state close to where it is needed, avoid unnecessary global state, standardize TypeScript and linting, automate testing and CI, and regularly remove unnecessary dependencies and abstractions.
11What would you put in a React project .env file?
AdvancedModel answer
I'd put configuration that is appropriate for the client environment, such as an API base URL or public feature configuration.
I would never treat a browser-exposed environment variable as a secret.
12How would you design a React project for multiple teams?
AdvancedModel answer
I'd organize the code around business domains, define ownership boundaries, establish a shared design system where appropriate, enforce dependency rules, standardize tooling and CI, and minimize cross-domain coupling.
Shared libraries would need clear ownership because excessive sharing can become an organizational bottleneck.
13What is the difference between project structure and architecture?
AdvancedModel answer
Project structure is how files and directories are organized.
Architecture is broader—it defines responsibilities, dependencies, boundaries, data flow, runtime behavior, and system-level decisions.
A clean folder structure doesn't automatically mean the application has good architecture.
14Would you recommend the same React project structure for every application?
AdvancedModel answer
No.
A small application should remain simple.
A large enterprise platform needs stronger boundaries.
I'd start with the simplest structure that supports the current requirements and evolve it as complexity grows.
15How would you prepare a React application for CI/CD?
AdvancedModel answer
I'd make the build reproducible, commit the lockfile, use a supported Node version, run dependency installation consistently, execute linting and tests, run the production build, perform security checks, generate the deployment artifact, and promote that artifact through environments.
Production-Ready Mental Model
A professional React project isn't just:
React
It is:
React Application│┌─────────────────┼─────────────────┐▼ ▼ ▼Source Tooling Configuration│ │ │▼ ▼ ▼Components Vite TypeScriptFeatures npm ESLintPages Build EnvironmentServices Test CI/CD│ │ │└─────────────────┼─────────────────┘▼Build Artifact│▼Deploy│▼Users
This is the mindset you should carry into enterprise React development.
Final Architecture
Remember this:
React Project│┌───────────┼───────────┐▼ ▼ ▼Source Tooling Configuration│ │ │▼ ▼ ▼Features Vite TypeScriptComponents npm EnvironmentPages Build ESLintServices Test CI/CD│ │ │└───────────┼───────────┘▼Application│▼Build│▼Deployment│▼Browser
The key principle is:
A React project should be designed not only to run today, but to remain understandable as the application, team, and business requirements grow.
Next Lesson
**React Project Structure**
In the next lesson, we'll go deeper into the project we just created and understand every important folder and file, including:
src/├── components/├── features/├── pages/├── hooks/├── services/├── types/├── utils/└── assets/
We'll also establish a production-grade React folder architecture that we'll reuse throughout the rest of this course.