Skip to main content

Stop Using Create React App in 2026

·PkgPulse Team

TL;DR

Create React App is dead. It was officially deprecated in 2023 and hasn't received a meaningful update since 2022. Installing it today means 1,200+ packages, Webpack 5 under the hood with 30-60 second build times, and no official support path forward. The React team removed it from their docs. Vite starts in 300ms, builds in under 5 seconds, and comes with first-class TypeScript support. There is no reason to use CRA in 2026.

Key Takeaways

  • CRA is officially deprecated — removed from React's official docs in 2023
  • 1,200+ transitive dependencies — massive attack surface, slow installs
  • Webpack under the hood — 30-60 second builds; Vite builds in 2-5 seconds
  • No update path — security vulnerabilities accumulate with no upstream fix
  • Vite is the answer — 300ms dev start, 2-5s builds, identical React support

What Happened to Create React App

Timeline:
2016: Facebook releases Create React App
      → Solves "configuration hell" of setting up React + Webpack + Babel
      → Huge success — developers can start in 30 seconds
      → "The blessed way to start React projects"

2018-2020: CRA dominates
      → ~20M weekly downloads at peak
      → Hundreds of tutorials built around it
      → Every bootcamp, every intro course uses CRA
      → Problem: it's accumulating tech debt faster than it's being maintained

2021: Cracks start showing
      → Webpack 5 migration is painful
      → Cold start times: 30+ seconds for medium apps
      → Hot reload: 5-15 seconds per save
      → Other tools (Next.js, Vite) are dramatically faster
      → CRA maintainers are burned out, community contribution drops

2022: CRA development effectively stops
      → Last major release: v5.0.1 (March 2022)
      → Open issues pile up (1,000+)
      → Security vulnerabilities go unpatched
      → The React team starts quietly recommending alternatives

2023: Official deprecation
      → React docs rewritten — CRA removed from recommendations
      → React team announces CRA is in "maintenance mode" (deprecated)
      → Recommended alternatives: Vite, Next.js, Remix
      → npm download count begins multi-year decline

2025-2026: Decline is complete
      → Downloads: still ~500K/week (from legacy CI pipelines and tutorials)
      → But new project starts: near zero
      → Every CRA project is technical debt waiting to be migrated

The Numbers That Killed CRA

# Install time comparison (2026):

# Create React App:
npx create-react-app my-app
# → Downloads: 1,300+ packages
# → Install time: 45-90 seconds (cold cache)
# → node_modules size: ~350MB
# → dev start time: 20-35 seconds
# → Hot reload: 5-15 seconds
# → Production build: 60-120 seconds

# Vite (React template):
npm create vite@latest my-app -- --template react-ts
# → Downloads: ~23 packages
# → Install time: 3-8 seconds
# → node_modules size: ~40MB
# → dev start time: 300ms
# → Hot reload: <100ms (HMR, not full reload)
# → Production build: 2-5 seconds

# Numbers don't lie:
# CRA dev start: 30s   vs Vite: 0.3s  → Vite is 100x faster to start
# CRA build: 90s       vs Vite: 3s    → Vite is 30x faster to build
# CRA packages: 1,300  vs Vite: 23    → CRA has 57x more dependencies
# CRA node_modules: 350MB vs Vite: 40MB → CRA takes 9x more disk space

CRA's Core Problem: Webpack

CRA is Webpack all the way down.
Every config decision in CRA was made to abstract away Webpack.
But Webpack's fundamental architecture is blocking:

Webpack (used by CRA):
→ JavaScript-native bundler
→ Processes every file synchronously during module resolution
→ Must scan and process ALL imports before starting dev server
→ 30 second start = 30 seconds of Webpack scanning your 500-file app
→ Hot reload requires rebuilding the affected module graph

Vite (what replaced it):
→ Uses esbuild (Go binary) for dependency pre-bundling
→ Serves files via native ES modules during development
→ Only processes files when the browser actually requests them
→ 300ms start = "I'm ready, request files as you need them"
→ Hot reload replaces only the changed module (no rebuild needed)

The performance difference isn't optimizations.
It's a fundamentally different architecture.
Webpack can't be optimized to match Vite.
The design decisions are incompatible.

What to Use Instead

# Scenario 1: New React SPA (no SSR needed)
npm create vite@latest my-app -- --template react-ts
cd my-app && npm install && npm run dev
# → TypeScript, React Fast Refresh, Vite, ready in under 10 seconds total

# Scenario 2: Next.js app (SSR, file-based routing, API routes)
npx create-next-app@latest my-app
# → Prompts for TypeScript, ESLint, Tailwind, App Router
# → Best choice if you need: SSR, SEO, server components, API routes

# Scenario 3: Full-stack with meta-framework
# Remix
npx create-remix@latest my-app
# → Full-stack, server-centric, data loading patterns

# Tanstack Start
npm create @tanstack/router@latest
# → Type-safe routing, file-based, works with Vite

# Scenario 4: You actually want a static site
npm create astro@latest
# → Build fast static sites, use React for interactive islands

# Decision guide:
# SPA (client-rendered, no SSR) → Vite
# SSR, SEO, server components → Next.js
# Full-stack, form-heavy → Remix
# Static, content-heavy → Astro
# Using CRA → Migrate to Vite

Migrating Existing CRA Projects to Vite

# Migration is surprisingly straightforward

# Step 1: Remove CRA
npm uninstall react-scripts

# Step 2: Install Vite
npm install --save-dev vite @vitejs/plugin-react

# Step 3: Create vite.config.ts
cat > vite.config.ts << 'EOF'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,  // Match CRA's default port
  },
})
EOF

# Step 4: Move index.html
# CRA: public/index.html
# Vite: index.html (root of project)
mv public/index.html .
# Add script tag to new index.html:
# <script type="module" src="/src/main.tsx"></script>

# Step 5: Update package.json scripts
{
  "scripts": {
    "start": "vite",          // was: react-scripts start
    "build": "vite build",    // was: react-scripts build
    "preview": "vite preview", // new: preview production build
    "test": "vitest"          // replace Jest with Vitest
  }
}

# Step 6: Handle environment variables
# CRA: process.env.REACT_APP_*
# Vite: import.meta.env.VITE_*
# → Search and replace: REACT_APP_ → VITE_

# Step 7: Fix absolute imports
# Add to vite.config.ts:
resolve: {
  alias: {
    '@': '/src',
  },
},

# That's the core migration. Most CRA apps migrate in 30-60 minutes.
# Common gotchas:
# → process.env → import.meta.env
# → REACT_APP_ prefix → VITE_ prefix
# → Jest config → Vitest config
# → CRA's built-in ESLint → add your own

The Ecosystem Moved On

Who still uses CRA?
→ Old tutorials on YouTube (pre-2023)
→ Bootcamp courses that haven't updated
→ Legacy enterprise projects from 2019-2022
→ Developers who haven't started a new project since 2022

Who the React ecosystem recommends:
React Docs (react.dev):
→ Next.js ← mentioned first
→ Remix
→ Gatsby (niche)
→ "Vite for SPAs" (effectively)
→ CRA: NOT LISTED

React community consensus (State of JS 2025):
→ Vite: 92% satisfaction rate
→ Next.js: 74% satisfaction
→ CRA: 32% satisfaction (mostly "meh, it used to work")
→ CRA usage intent: negative (more people leaving than joining)

The message is clear:
CRA solved a 2016 problem with 2016 tools.
Vite solved the same problem with 2021 tools.
The performance difference is 10-100x.
There is no reason to use CRA in 2026.

If You're Stuck With CRA (Enterprise Reality)

# You have a 200,000 line CRA app and can't migrate right now.
# What do you do?

# 1. Pin your CRA version
{
  "dependencies": {
    "react-scripts": "5.0.1"  // Last stable version, pin it
  }
}

# 2. Override vulnerable transitive dependencies
{
  "overrides": {
    "semver": ">=7.5.2",
    "nth-check": ">=2.0.1",
    "postcss": ">=8.4.31"
  }
}
# This patches CVEs without needing upstream fixes

# 3. Suppress npm audit noise (CRA will always fail audit)
# .npmrc
# legacy-peer-deps=true
# audit=false  ← do NOT do this for security reasons
# Instead: npm audit --audit-level=critical
# Only fail on truly critical vulns, not the hundreds of low/moderate

# 4. Plan the migration
# Migrate one route at a time using module federation or separate Vite apps
# For very large apps: create new routes as Vite micro-frontends
# Run CRA and Vite apps side by side behind a reverse proxy

# 5. Schedule the migration
# CRA is dead weight. It's not a matter of if, but when.
# Every month you wait: more security debt, more friction, slower builds.
# Set a date. Migrate.

Compare Vite vs Webpack (the bundler under CRA) at PkgPulse.

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.