Voltar para o Blog

Create React App Depreciado: Migrando para Vite e o Futuro do React em 2025

Olá HaWkers, fevereiro de 2025 marcou o fim de uma era: o Create React App (CRA) foi oficialmente depreciado pelo time do React.

Você se lembra quando npx create-react-app my-app era a forma padrão de iniciar qualquer projeto React? Essa era acabou, e uma nova começou.

O Anúncio Oficial

Em 14 de fevereiro de 2025, o time do React publicou no blog oficial: "Sunsetting Create React App". A mensagem foi clara:

"Create React App foi depreciado para novos apps. Aplicações existentes devem migrar para um framework, ou migrar para uma build tool como Vite, Parcel, ou RSBuild."

Por Que Create React App Foi Depreciado?

Vários fatores levaram a esta decisão:

1. Velocidade de Build

# Create React App (Webpack)
npm start
# Cold start: ~30-45 segundos
# Hot reload: ~2-5 segundos

# Vite (Rollup + esbuild)
npm run dev
# Cold start: ~1-3 segundos 🚀
# Hot reload: ~50-200ms ⚡

2. Manutenção Estagnada

  • Última atualização significativa: 2021
  • Issues acumuladas sem resposta
  • Dependências desatualizadas

3. Mudança de Paradigma
O React mudou sua recomendação de SPA (Single Page Application) para frameworks full-stack com Server Components.

As Alternativas Recomendadas

O time do React recomenda três caminhos diferentes dependendo do seu caso de uso:

1. Frameworks Full-Stack (Recomendação Principal)

Next.js (Vercel)

npx create-next-app@latest my-app

Ideal para:

  • Sites e aplicações de produção
  • SEO é importante
  • Servidor e cliente integrados
  • Você quer React Server Components

Remix (Shopify)

npx create-remix@latest my-app

Ideal para:

  • Performance otimizada
  • Progressive enhancement
  • Nested routing avançado

2. Build Tools Modernas (Para SPAs)

Vite (Recomendação para SPAs)

npm create vite@latest my-app -- --template react-ts

Ideal para:

  • SPAs tradicionais
  • Prototipagem rápida
  • Aplicações sem necessidade de SSR
  • Máxima velocidade de desenvolvimento

Parcel

npx create-react-app my-app --template parcel

Ideal para:

  • Zero configuração
  • Build simples

RSBuild (Baseado em Rspack)

npm create rsbuild@latest my-app

Ideal para:

  • Performance extrema
  • Compatibilidade com Webpack

Migração de CRA para Vite: Guia Passo a Passo

Vamos migrar um projeto Create React App existente para Vite. Este é o caminho mais comum para SPAs.

Passo 1: Análise do Projeto Atual

# Projeto CRA típico
my-app/
├── public/
   ├── index.html
   └── favicon.ico
├── src/
   ├── App.tsx
   ├── index.tsx
   └── ...
├── package.json
└── node_modules/

Passo 2: Backup e Preparação

# Criar branch para migração
git checkout -b migrate-to-vite

# Backup do package.json
cp package.json package.json.backup

Passo 3: Instalar Vite

# Remover dependências do CRA
npm uninstall react-scripts

# Instalar Vite e plugins
npm install -D vite @vitejs/plugin-react

Passo 4: Criar vite.config.ts

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  plugins: [react()],

  // Resolver paths (se você usava jsconfig.json ou tsconfig paths)
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
      '@utils': path.resolve(__dirname, './src/utils'),
    }
  },

  // Configuração de servidor dev
  server: {
    port: 3000,
    open: true,
    host: true
  },

  // Build config
  build: {
    outDir: 'dist',
    sourcemap: true,
    // Configuração para chunk splitting otimizado
    rollupOptions: {
      output: {
        manualChunks: {
          'react-vendor': ['react', 'react-dom', 'react-router-dom'],
          'ui-vendor': ['@mui/material', '@emotion/react', '@emotion/styled']
        }
      }
    }
  },

  // Variáveis de ambiente
  envPrefix: 'VITE_',

  // CSS
  css: {
    modules: {
      localsConvention: 'camelCase'
    }
  }
});

Passo 5: Mover e Atualizar index.html

# CRA mantém index.html em public/
# Vite precisa dele na raiz
mv public/index.html index.html

Atualizar o index.html:

<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>

    <!-- IMPORTANTE: Vite precisa desta referência -->
    <script type="module" src="/src/index.tsx"></script>
  </body>
</html>

Passo 6: Atualizar Variáveis de Ambiente

# CRA usa REACT_APP_*
REACT_APP_API_URL=https://api.example.com
REACT_APP_API_KEY=abc123

# Vite usa VITE_*
VITE_API_URL=https://api.example.com
VITE_API_KEY=abc123

Atualizar código:

// Antes (CRA)
const apiUrl = process.env.REACT_APP_API_URL;
const apiKey = process.env.REACT_APP_API_KEY;

// Depois (Vite)
const apiUrl = import.meta.env.VITE_API_URL;
const apiKey = import.meta.env.VITE_API_KEY;

Para TypeScript, criar src/vite-env.d.ts:

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string;
  readonly VITE_API_KEY: string;
  // Adicione outras variáveis aqui
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

Passo 7: Atualizar package.json Scripts

{
  "name": "my-app",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
  },
  "dependencies": {
    "react": "^18.3.0",
    "react-dom": "^18.3.0"
  },
  "devDependencies": {
    "@types/react": "^18.3.0",
    "@types/react-dom": "^18.3.0",
    "@vitejs/plugin-react": "^4.3.0",
    "typescript": "^5.6.0",
    "vite": "^5.4.0"
  }
}

Passo 8: Ajustes Comuns

1. Importações de Assets

// CRA permite importar arquivos da pasta public
// ❌ Não funciona no Vite
<img src="/images/logo.png" alt="Logo" />

// ✅ Vite
import logoUrl from './assets/logo.png';
<img src={logoUrl} alt="Logo" />

// Ou mantenha na pasta public e use caminho absoluto
// public/images/logo.png
<img src="/images/logo.png" alt="Logo" />

2. SVG como Componentes

// CRA com SVGR embutido
import { ReactComponent as Logo } from './logo.svg';

// Vite precisa de configuração
npm install -D vite-plugin-svgr
// vite.config.ts
import svgr from 'vite-plugin-svgr';

export default defineConfig({
  plugins: [
    react(),
    svgr()
  ]
});
// Agora funciona
import { ReactComponent as Logo } from './logo.svg?react';

3. Global CSS

// index.tsx ou App.tsx
import './index.css';
import './App.css';

Funciona da mesma forma, sem mudanças.

4. CSS Modules

// Button.module.css
.button {
  background: blue;
}

// Button.tsx
import styles from './Button.module.css';

function Button() {
  return <button className={styles.button}>Click</button>;
}

Funciona da mesma forma.

Passo 9: Testar a Migração

# Desenvolvimento
npm run dev

# Build de produção
npm run build

# Preview do build
npm run preview

Exemplo Completo: App Antes e Depois

Projeto CRA Original

// src/index.tsx (CRA)
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

reportWebVitals();
// src/App.tsx (CRA)
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  const apiUrl = process.env.REACT_APP_API_URL;

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>API URL: {apiUrl}</p>
      </header>
    </div>
  );
}

export default App;

Projeto Vite Migrado

// src/main.tsx (Vite - renomeado de index.tsx)
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
// src/App.tsx (Vite)
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  const apiUrl = import.meta.env.VITE_API_URL;

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>API URL: {apiUrl}</p>
      </header>
    </div>
  );
}

export default App;

Mudanças mínimas!

Migração para Next.js: Quando Fazer Sentido

Se sua aplicação precisa de:

  • SEO otimizado
  • Server-side rendering
  • API routes integradas
  • React Server Components

Considere migrar para Next.js ao invés de Vite.

Setup Básico Next.js

npx create-next-app@latest my-app
// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="pt-BR">
      <body>{children}</body>
    </html>
  );
}

// app/page.tsx
export default function HomePage() {
  return (
    <main>
      <h1>Welcome to Next.js 15</h1>
    </main>
  );
}

// app/api/users/route.ts (API Route)
export async function GET() {
  const users = await fetchUsers();
  return Response.json(users);
}

Comparação de Performance

Tempo de Build

# Create React App (Webpack)
npm run build
# Tempo: ~45-60 segundos
# Bundle size: ~200-300 KB (minified + gzipped)

# Vite (Rollup + esbuild)
npm run build
# Tempo: ~5-10 segundos 🚀
# Bundle size: ~150-200 KB (minified + gzipped)

# Melhoria: 6-10x mais rápido

Tempo de Dev Server

# CRA
npm start
# Cold start: 30-45s
# Hot reload: 2-5s

# Vite
npm run dev
# Cold start: 1-3s 🚀
# Hot reload: 50-200ms ⚡

# Melhoria: 10-30x mais rápido

Bundle Analysis

// Vite permite análise fácil
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
  plugins: [
    react(),
    visualizer({
      open: true,
      filename: 'dist/stats.html'
    })
  ]
});

Troubleshooting: Problemas Comuns

1. "require is not defined"

// ❌ CommonJS não funciona no Vite
const module = require('./module');

// ✅ Use ES modules
import module from './module';

2. "process is not defined"

// ❌ Não funciona
if (process.env.NODE_ENV === 'production') {}

// ✅ Vite way
if (import.meta.env.PROD) {}

Ou configure no vite.config.ts:

export default defineConfig({
  define: {
    'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
  }
});

3. Absolute Imports

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
// vite.config.ts
resolve: {
  alias: {
    '@': path.resolve(__dirname, './src')
  }
}

4. Polyfills

# Vite não inclui polyfills automaticamente
npm install -D @vitejs/plugin-legacy
// vite.config.ts
import legacy from '@vitejs/plugin-legacy';

export default defineConfig({
  plugins: [
    react(),
    legacy({
      targets: ['defaults', 'not IE 11']
    })
  ]
});

O Futuro do Tooling React

Tendências para 2025-2026

1. Vite como Padrão

  • Stack Overflow Survey 2025: Vite supera Webpack
  • Adotado por Vue, React, Svelte, Solid

2. Rspack (Rust-based)

  • Compatível com Webpack
  • Performance próxima ao Vite
  • Migração mais fácil de projetos Webpack grandes

3. Turbopack (Vercel)

  • Integrado ao Next.js
  • Escrito em Rust
  • Promete ser ainda mais rápido que Vite

4. Farm (Nova Geração)

  • Extremamente rápido
  • Compatibilidade com Vite plugins
  • Otimizações automáticas
// Visão do futuro
const reactToolingFuture = {
  build_tools: {
    dominant: 'Vite',
    emerging: ['Rspack', 'Turbopack', 'Farm'],
    declining: ['Webpack', 'Create React App']
  },

  frameworks: {
    ssr: ['Next.js', 'Remix', 'Gatsby'],
    spa: 'Vite + React',
    hybrid: 'Emerging patterns'
  },

  developer_experience: {
    startup_time: '<1 second',
    hot_reload: '<100ms',
    build_time: '<10 seconds'
  }
};

Checklist de Migração

- [ ] Backup do projeto (git branch ou cópia)
- [ ] Instalar Vite e dependências
- [ ] Criar vite.config.ts
- [ ] Mover index.html para raiz
- [ ] Atualizar index.html com script module
- [ ] Renomear variáveis de ambiente (REACT_APP_* → VITE_*)
- [ ] Atualizar código para import.meta.env
- [ ] Ajustar imports de assets se necessário
- [ ] Configurar SVGR se usar SVG como componentes
- [ ] Atualizar scripts do package.json
- [ ] Testar npm run dev
- [ ] Testar npm run build
- [ ] Testar npm run preview
- [ ] Verificar funcionalidades críticas
- [ ] Atualizar CI/CD se necessário
- [ ] Atualizar documentação do projeto

Se você está interessado em outras mudanças importantes no ecossistema React, recomendo dar uma olhada em outro artigo: React Foundation: A Nova Era do Ecossistema React Sob a Linux Foundation onde você vai descobrir como a governança do React está mudando em 2025.

Bora pra cima! 🦅

📚 Quer Aprofundar Seus Conhecimentos em JavaScript?

Este artigo cobriu ferramentas de build modernas para React, mas há muito mais para explorar no desenvolvimento web moderno.

Desenvolvedores que investem em conhecimento sólido e estruturado tendem a ter mais oportunidades no mercado.

Material de Estudo Completo

Se você quer dominar JavaScript do básico ao avançado, preparei um guia completo:

Opções de investimento:

  • R$9,90 (pagamento único)

👉 Conhecer o Guia JavaScript

💡 Material atualizado com as melhores práticas do mercado

Comentários (0)

Esse artigo ainda não possui comentários 😢. Seja o primeiro! 🚀🦅

Adicionar comentário