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.

flowchart LR
    V["Vite"] --> |"< 300ms"| S["Dev Server"]
    C["CRA"] --> |"~30s"| S2["Dev Server"]
    
    style V fill:#646cff
    style C fill:#61dafb


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
WarningCRA is Dead

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 --version

Quick 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 dev

That’s it. Your app is running at http://localhost:5173.


Interactive Setup

For more control, run without the template flag:

npm create vite@latest

You’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

TipESLint catches bugs. Prettier fixes style.

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.


ESLint 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.sh

VS 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:

  1. Learn React fundamentals — Components, props, state
  2. Master hooks — useEffect, useCallback, custom hooks
  3. Add routing — React Router for navigation
  4. Manage state — Zustand, TanStack Query
  5. 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.