React Building and Deploying Apps

Building a React app converts your development code into optimized, production-ready files. Deploying sends those files to a server so users worldwide can access the app. This topic covers the build process, environment variables, and popular deployment platforms.

Development vs Production Build

Diagram: What changes between development and production

DEVELOPMENT BUILD:
  ├── Source maps included (debug-friendly)
  ├── Error messages are verbose
  ├── No minification (readable code)
  ├── Hot module replacement active
  └── Bundle size: ~2 MB+

PRODUCTION BUILD:
  ├── Code minified and compressed
  ├── Dead code eliminated (tree shaking)
  ├── Split into optimized chunks
  ├── Assets hashed for cache busting
  └── Bundle size: ~100-400 KB (gzipped)

Creating a Production Build

With Vite (recommended)

npm run build

Vite outputs files to the dist/ folder:

dist/
  index.html
  assets/
    index-abc123.js     ← Main bundle (hashed filename)
    index-def456.css    ← CSS bundle
    vendor-ghi789.js    ← Third-party libraries
    images/
      logo-jkl012.png

The hash in the filename (like abc123) changes every time the file content changes. This busts browser cache — users always get the latest version.

With Create React App

npm run build

Output goes to the build/ folder with the same structure.

Environment Variables

Never hardcode API URLs, keys, or environment-specific values in your source code. Use environment variables to keep them separate.

Vite environment variables

# .env.development (used during npm run dev)
VITE_API_URL=http://localhost:3000/api
VITE_DEBUG=true

# .env.production (used during npm run build)
VITE_API_URL=https://api.myapp.com
VITE_DEBUG=false
// In your component — must start with VITE_
const API_URL = import.meta.env.VITE_API_URL;

const response = await fetch(`${API_URL}/users`);

Create React App environment variables

# .env
REACT_APP_API_URL=https://api.myapp.com
// In your component — must start with REACT_APP_
const API_URL = process.env.REACT_APP_API_URL;

Never commit .env files with secrets (API keys, passwords) to version control. Add .env to .gitignore and store secrets in your deployment platform's environment settings.

Deploying to Vercel

Vercel is the most popular platform for React app deployment. It detects Vite and Create React App automatically.

Step 1: Push your code to GitHub

Step 2: Go to vercel.com and sign in with GitHub

Step 3: Click "New Project" → Import your repository

Step 4: Vercel auto-detects Vite / Create React App
  Build Command: npm run build
  Output Directory: dist (Vite) or build (CRA)

Step 5: Add environment variables in Vercel dashboard
  (Settings → Environment Variables)

Step 6: Click Deploy
  └── Your app is live at: yourapp.vercel.app

Every push to the main branch triggers an automatic redeploy. Pull requests get preview URLs for testing before merging.

Deploying to Netlify

Step 1: Push code to GitHub

Step 2: Go to netlify.com → "New site from Git"

Step 3: Connect GitHub and select your repository

Step 4: Configure build settings:
  Build command: npm run build
  Publish directory: dist

Step 5: Add environment variables:
  Site settings → Environment variables

Step 6: Click Deploy site
  └── Live at: yourapp.netlify.app

Deploying to GitHub Pages

npm install --save-dev gh-pages
// package.json
{
  "homepage": "https://yourusername.github.io/repo-name",
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d dist"
  }
}
npm run deploy

GitHub Pages serves static files from a repository. It works for React apps but has limitations — no server-side rendering and routes need special configuration for React Router.

Fixing 404 Errors on Page Refresh

React Router handles routes in the browser. When a user refreshes a page like /dashboard, the server tries to find a dashboard.html file — which does not exist. The server returns 404.

Fix this by redirecting all routes to index.html:

Netlify: add a _redirects file in public/

/*  /index.html  200

Vercel: add a vercel.json file

{
  "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}

Checking Build Size

npm run build

# Vite shows bundle sizes after build:
✓ built in 4.52s
dist/assets/index-abc.js    85.32 kB │ gzip: 28.10 kB
dist/assets/vendor-def.js  142.10 kB │ gzip: 45.80 kB

# Target: initial bundle under 200 KB gzipped
# Large bundles: add more code splitting

Performance Checklist Before Deployment

✓ Run npm run build successfully
✓ Test the production build locally: npm run preview (Vite)
✓ Check bundle size — split large chunks with React.lazy
✓ All environment variables set in deployment platform
✓ .env files added to .gitignore
✓ 404 redirect configured for React Router
✓ Error boundary added around main content
✓ App tested in Chrome, Firefox, Safari, and mobile browsers

Previewing Production Build Locally

Test the production build on your computer before deploying.

# Vite
npm run build
npm run preview
# Opens at http://localhost:4173

# Create React App
npm run build
npx serve -s build
# Opens at http://localhost:3000

Continuous Deployment

Both Vercel and Netlify support continuous deployment. Every push to the main branch automatically builds and deploys the app. Pull request branches get unique preview URLs — share them with your team to review changes before merging.

Code push to GitHub → Deployment platform detects push
                    → Runs npm run build automatically
                    → Deploys to production URL
                    → Sends success/failure notification

Summary

Run npm run build to create a production-optimized bundle. Vite outputs to dist/ and CRA to build/. Use environment variables prefixed with VITE_ or REACT_APP_ for configuration that differs between development and production. Vercel and Netlify are the simplest deployment platforms — connect your GitHub repository and they handle the rest automatically. Fix refresh-page 404 errors with a redirect rule that points all routes to index.html. Always test the production build locally with npm run preview before shipping.

Leave a Comment

Your email address will not be published. Required fields are marked *