flowchart LR
V["Vite"] --> |"< 300ms"| S["Dev Server"]
C["CRA"] --> |"~30s"| S2["Dev Server"]
style V fill:#646cff
style C fill:#61dafb
Setup React App Locally in Seconds
Before diving into code architecture and patterns, you need a working React app to experiment with. In the past, create-react-app (CRA) was the standard. Today, Vite has completely replaced it as the modern standard.
Vite vs Create React App
| Feature | Vite | Create React App |
|---|---|---|
| Dev server startup | < 300ms | 30-60 seconds |
| Hot Module Replacement | Instant | Slow |
| Build time | Fast (Rollup) | Slow (Webpack) |
| Bundle size | Optimized | Larger |
| TypeScript | Native | Requires setup |
| Maintained | Active | Deprecated |
Create React App is no longer maintained. The React team officially recommends Vite or Next.js for new projects.
Prerequisites
Before you start, ensure you have:
- Node.js v18 or higher
- npm, pnpm, or yarn
# Check your versions
node --version # Should be 18+
npm --versionQuick Start (One Command)
# Create a new React + TypeScript project
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run devThat’s it. Your app is running at http://localhost:5173.
Interactive Setup
For more control, run without the template flag:
npm create vite@latestYou’ll be prompted:
✔ Project name: my-app
✔ Select a framework: › React
✔ Select a variant: › TypeScript + SWC
SWC is a Rust-based compiler that’s 20x faster than Babel.
Project Structure
my-app/
├── public/
│ └── vite.svg
├── src/
│ ├── assets/
│ │ └── react.svg
│ ├── App.css
│ ├── App.tsx
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
| File | Purpose |
|---|---|
index.html |
Entry HTML file (Vite injects script) |
src/main.tsx |
React entry point |
src/App.tsx |
Root component |
vite.config.ts |
Vite configuration |
tsconfig.json |
TypeScript configuration |
Essential Additions
After scaffolding, add these immediately:
Path Aliases
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
});// tsconfig.json - add to compilerOptions
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}Now you can import like:
import { Button } from '@/components/Button';
Environment Variables
# .env
VITE_API_URL=http://localhost:3000
VITE_APP_NAME=My App// Access in code (must prefix with VITE_)
const apiUrl = import.meta.env.VITE_API_URL;
Code Quality Tools: ESLint & Prettier
Before diving into dependencies, let’s understand why these tools are non-negotiable in modern React development.
What They Do
| Tool | Purpose | Catches |
|---|---|---|
| ESLint | Static analysis — finds bugs before runtime | Unused variables, missing dependencies in hooks, unreachable code |
| Prettier | Auto-formatting — enforces consistent style | Inconsistent indentation, quote styles, line lengths |
Why You Need Both
They solve different problems and work together seamlessly.
ESLint is your first line of defense. It analyzes your code without running it, catching issues like:
- Forgotten dependencies in
useEffect(a common source of bugs) - Unused imports cluttering your bundle
- Accessibility violations in JSX
- React-specific anti-patterns like conditional hooks
Prettier ends all formatting debates. It rewrites your code to a consistent style, so teams never argue about tabs vs. spaces or trailing commas again.
How They Work Together
flowchart LR
C["Your Code"] --> E["ESLint"]
E --> |"Bug? Error!"| F["Fix Issues"]
E --> |"Clean"| P["Prettier"]
P --> |"Formatted"| S["Save"]
style E fill:#4b32c3
style P fill:#f7b93e
eslint-config-prettier disables ESLint’s formatting rules so the two tools don’t conflict.
Recommended Dev Dependencies
# ESLint + Prettier
npm install -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-react-hooks prettier eslint-config-prettier
# Testing
npm install -D vitest @testing-library/react @testing-library/user-event jsdom
# CSS
npm install -D sass # If using SCSSESLint Configuration
// .eslintrc.cjs
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'prettier',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
},
};Scripts Reference
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives",
"format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
"test": "vitest",
"test:coverage": "vitest --coverage"
}
}| Script | What it does |
|---|---|
npm run dev |
Start dev server with HMR |
npm run build |
Production build to dist/ |
npm run preview |
Preview production build locally |
npm run lint |
Check for code issues |
npm run test |
Run tests in watch mode |
Shell Script for Automation
Save this as create-react.sh for quick project creation:
#!/usr/bin/env bash
# Prompt for project name
read -p "Enter project name (default: my-app): " APP_NAME
APP_NAME=${APP_NAME:-my-app}
# Prompt for TypeScript
read -p "Use TypeScript? (y/n, default: y): " USE_TS
USE_TS=${USE_TS:-y}
echo "🚧 Creating project: $APP_NAME"
if [ "$USE_TS" == "y" ]; then
npm create vite@latest "$APP_NAME" -- --template react-ts
else
npm create vite@latest "$APP_NAME" -- --template react
fi
cd "$APP_NAME"
echo "📦 Installing dependencies..."
npm install
echo "🛠️ Adding dev tools..."
npm install -D vitest @testing-library/react jsdom
echo "🚀 Starting dev server..."
npm run dev# Make executable and run
chmod +x create-react.sh
./create-react.shVS Code Extensions
For the best development experience:
- ES7+ React/Redux/GraphQL snippets — Quick component scaffolding
- ESLint — Inline linting
- Prettier — Auto-formatting
- TypeScript Vue Plugin (Volar) — Better TypeScript support
- Auto Rename Tag — Rename paired tags
What’s Next?
With your app running, you’re ready to:
- Learn React fundamentals — Components, props, state
- Master hooks — useEffect, useCallback, custom hooks
- Add routing — React Router for navigation
- Manage state — Zustand, TanStack Query
- Style your app — CSS Modules, Tailwind, or styled-components
Your React journey starts now. Keep this app running as you work through the rest of this book—every concept can be practiced immediately.