Every React project begins with tooling decisions. The ecosystem has evolved significantly: Create React App is deprecated, and Vite is the modern standard for fast, reliable React development. Getting the foundation right — TypeScript strictness, folder structure, and HMR — sets the tone for everything that follows.
- Initialize a React + TypeScript project using Vite
- Configure
tsconfig.jsonwithstrict: trueand understand what that enables - Establish a scalable folder structure for a real application
- Verify Hot Module Replacement (HMR) is working correctly
- Replace generated boilerplate with intentional, semantic markup
The start/ directory contains a pre-scaffolded Vite + React + TypeScript project so you can npm install && npm run dev immediately. The steps below describe how that project was created — follow along to understand each decision, or try it yourself in a scratch directory.
Use Vite to create a new React + TypeScript project:
npm create vite@latest .
npm installWhen prompted, select React and then TypeScript.
Open tsconfig.json (or tsconfig.app.json) and confirm "strict": true is set. If it is not, add it under compilerOptions. Strict mode enables:
strictNullChecks— no implicitnullorundefinednoImplicitAny— all variables must have inferrable typesstrictFunctionTypes— stricter function type checking- And several others that catch real bugs at compile time
Create the following directories inside src/:
src/
components/ # Reusable UI components
hooks/ # Custom React hooks
types/ # Shared TypeScript type definitions
utils/ # Pure utility/helper functions
assets/ # Static assets (images, fonts, icons)
Add a .gitkeep file to each empty directory so Git tracks them:
touch src/components/.gitkeep
touch src/hooks/.gitkeep
touch src/types/.gitkeep
touch src/utils/.gitkeep
touch src/assets/.gitkeepReplace src/App.tsx with a clean TaskFlow layout. The rendered output must include:
- A heading: TaskFlow
- A subtitle: Project Management, Simplified.
- A footer: Built with React + TypeScript
Use semantic HTML elements (<header>, <main>, <footer>).
npm run dev # Dev server starts, HMR active
npm run build # Zero TypeScript errors, zero warningsMake a small edit to App.tsx while npm run dev is running and confirm the browser updates without a full page reload — that is HMR working.
-
npm run devstarts successfully and the app renders in the browser -
npm run buildcompletes with zero errors -
tsconfig.jsonortsconfig.app.jsonhas"strict": true - The rendered page shows the heading "TaskFlow"
- The rendered page shows the subtitle "Project Management, Simplified."
- The rendered page shows the footer "Built with React + TypeScript"
- Semantic HTML is used (
<header>,<main>,<footer>) - Folder structure matches:
components/,hooks/,types/,utils/,assets/ - No
anytypes in any.tsor.tsxfile
Select the right variant. When running npm create vite@latest interactively, you must choose "React" then "TypeScript" (not "TypeScript + SWC" if you want standard Babel).
Keep tsconfig.node.json. Vite generates two tsconfig files: tsconfig.app.json for your source code and tsconfig.node.json for the Vite config file itself. Do not delete tsconfig.node.json — it is required for vite.config.ts to type-check correctly.
Keep vite-env.d.ts. The file src/vite-env.d.ts contains /// <reference types="vite/client" />. This is what gives you type definitions for import.meta.env and other Vite-specific globals. Deleting it breaks those types.
tsconfig.json is a composite root. In Vite's template, the top-level tsconfig.json uses "references" to point at tsconfig.app.json and tsconfig.node.json. It does not have compilerOptions of its own. The strict settings live in tsconfig.app.json.
01-project-setup/
index.html
vite.config.ts
tsconfig.json
tsconfig.app.json
tsconfig.node.json
package.json
src/
main.tsx
App.tsx
App.css
index.css
vite-env.d.ts
components/
hooks/
types/
utils/
assets/
public/