Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA
LiçãoIniciantecódigo testado

Criar projeto React com Vite: passo a passo

npm create vite, o que cada arquivo do projeto faz, como o main.jsx liga o componente ao HTML e o que dá para apagar antes de começar.

Rodolfo Mori16 min de leitura

Você só queria ver sua primeira tela React, mas o terminal pergunta por framework, variante e template. Depois surgem arquivos desconhecidos, a pasta node_modules e comandos parecidos. Nesta aula, você vai da pasta vazia a uma agenda no navegador sabendo quem criou, instalou e executou cada parte.

React descreve os componentes da interface, mas não cria a estrutura do projeto nem prepara sua publicação. O Vite organiza esse fluxo; o npm baixa pacotes e executa comandos. Já create-vite é um scaffolder (gerador de estrutura inicial): ele aplica um template, um modelo pronto de arquivos e configurações.

Pense num kit de montagem: create-vite entrega peças e manual, npm install traz o material listado, npm run dev liga a bancada e npm run build fecha a caixa que vai para a hospedagem. A comparação termina aí: no projeto, o Vite lê, transforma e conecta arquivos de código.

Os comandos e resultados abaixo foram testados no macOS com Node 24.16.0 e npm 11.13.0. A Pata Serena é uma clínica veterinária fictícia, criada apenas para dar contexto ao exemplo. Se React ainda for novidade, leia o que é React antes de continuar.

Como criar um projeto React com Vite?

Use o gerador create-vite com o template React. Ele cria a pasta e os arquivos iniciais, mas ainda não baixa as dependências nem abre o projeto no navegador.

Abra o terminal, o programa em que a gente executa comandos de texto, na pasta onde você guarda seus projetos e rode:

bash
npm create vite@latest clinica-vet -- --template react
> npx > "create-vite" clinica-vet --template react

│ ◇ Scaffolding project in /private/tmp/pata-serena/clinica-vet… │ └ Done. Now run:

cd clinica-vet npm install npm run dev

Leia o comando da esquerda para a direita:

  • npm create pede ao npm que execute um gerador temporário.
  • vite@latest escolhe o pacote create-vite na versão marcada como latest no registro do npm.
  • clinica-vet será o nome da pasta e do projeto.
  • O primeiro -- separa os argumentos do npm dos argumentos enviados ao gerador.
  • --template react escolhe o modelo React sem abrir perguntas interativas.

O gerador só escreveu arquivos. Com --template react, ele não fez perguntas. Sem essa opção, um assistente pede:

  1. Project name — nome da pasta e campo name do package.json; prefira minúsculas e hífen, como clinica-vet.
  2. Select a framework — framework é um conjunto de ferramentas e convenções para estruturar a aplicação; aqui você escolhe React.
  3. Select a variant — variante é uma configuração dentro do framework, como JavaScript, TypeScript ou uma opção com React Compiler.

Depois do framework, aparecem apenas variantes compatíveis. Opções com seta, como RSC e React Router, chamam o instalador de outro projeto. --template react pula as perguntas; --help mostra os templates aceitos.

CLI significa command-line interface: programa controlado pelo terminal. RSC significa React Server Components; React Compiler é uma ferramenta de otimização do React.

Experimente você mesmo: o template aparece na ajuda?

Antes de executar o próximo comando, preveja dois nomes que devem aparecer: react para JavaScript e react-ts para TypeScript. Depois compare sua previsão com a seção Available templates da saída.

bash
npx create-vite@latest --help
Usage: create-vite [OPTION]... [DIRECTORY]

Create a new Vite project in JavaScript or TypeScript. When running in TTY, the CLI will start in interactive mode.

Options: -t, –template NAME use a specific template -i, –immediate / –no-immediate install dependencies and start dev –eslint / –no-eslint use ESLint instead of Oxlint (only for React templates) –overwrite remove existing files if target directory is not empty –interactive / –no-interactive force interactive / non-interactive mode -h, –help display this help message

Available templates: vanilla-ts vanilla vue-ts vue react-ts react react-compiler-ts react-compiler preact-ts preact lit-ts lit svelte-ts svelte solid-ts solid qwik-ts qwik

O par react-ts / react confirma sua previsão. A lista mostra apenas templates internos do create-vite; outras escolhas do assistente usam CLIs próprias. --eslint troca o Oxlint pelo ESLint. Ambos são linters: analisam o código sem executá-lo e apontam padrões problemáticos.

Quais arquivos o Vite cria no projeto?

O gerador cria o código-fonte, o HTML inicial e os arquivos que descrevem como instalar e executar o projeto. Ele ainda não baixa pacotes; por isso vale olhar o esqueleto antes de usar npm install.

Entre na pasta criada e liste os arquivos:

bash
cd clinica-vet
find . -type f | sort
./.gitignore ./.oxlintrc.json ./README.md ./index.html ./package.json ./public/favicon.svg ./public/icons.svg ./src/App.css ./src/App.jsx ./src/assets/hero.png ./src/assets/react.svg ./src/assets/vite.svg ./src/index.css ./src/main.jsx ./vite.config.js

Quinze arquivos. Nenhuma pasta node_modules ainda — esse é o diretório em que o npm guardará os pacotes instalados. O create-vite só escreve o esqueleto.

src significa source: é onde fica o código-fonte que você edita. Um ponto de entrada é o primeiro arquivo de código carregado para iniciar a aplicação. Configuração é o conjunto de opções que orienta uma ferramenta. E hash é uma impressão curta calculada a partir do conteúdo; veremos seu efeito no build. Com esses nomes no lugar, veja o papel de cada arquivo:

arquivo para que serve você mexe?
index.html a única página real do projeto; contém a div onde o React monta sim, no título e nas meta tags
package.json nome, dependências e os scripts dev, build, lint e preview sim, ao instalar biblioteca
vite.config.js configuração do Vite; já vem com o plugin do React ligado raramente
.oxlintrc.json regras do linter, incluindo react/rules-of-hooks raramente
src/main.jsx o ponto de entrada: liga o React ao index.html quase nunca
src/App.jsx o componente raiz — a tela que você vê sim, o tempo todo
src/index.css estilo global da página sim
src/App.css estilo da tela de boas-vindas sim (ou apaga)
src/assets/ imagens importadas pelo JavaScript, com hash no build sim
public/ arquivos servidos crus, sem passar pelo Vite às vezes

A diferença entre src/assets/ e public/ confunde no começo. Em src/assets, a imagem é importada no código (import logo from './assets/logo.svg'), o Vite a processa e coloca um hash no nome. Em public/, o arquivo é copiado tal e qual para a raiz do site: o favicon.svg chega como /favicon.svg, com esse nome exato, porque o index.html o referencia direto.

O package.json do template é curto:

json
{
  "name": "clinica-vet",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "oxlint",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^19.2.8",
    "react-dom": "^19.2.8"
  },
  "devDependencies": {
    "@types/react": "^19.2.17",
    "@types/react-dom": "^19.2.3",
    "@vitejs/plugin-react": "^6.0.4",
    "oxlint": "^1.75.0",
    "vite": "^8.2.0"
  }
}

package.json é o manifesto do projeto: registra nome, comandos e pacotes. O campo type: module diz ao Node para interpretar import e export como módulos JavaScript. Um módulo é um arquivo que pode importar ou exportar partes do programa. Já scripts cria atalhos nomeados para comandos maiores.

Só duas dependências de produção — pacotes necessários para a aplicação funcionar — aparecem: react e react-dom. As devDependencies são ferramentas usadas para desenvolver, analisar e construir o projeto. O ^ permite atualizações compatíveis dentro das regras de versionamento do npm. O artigo sobre npm e package.json destrincha cada campo e o arquivo de lock.

Como index.html, main.jsx e App.jsx se conectam?

O navegador abre index.html; esse HTML carrega main.jsx; então main.jsx liga React à div raiz e pede para renderizar App. São três arquivos com três responsabilidades, conectados numa sequência.

O index.html não fica escondido dentro de public/: ele é o ponto de partida e permanece na raiz. O DOM é a árvore de objetos que o navegador cria a partir desse HTML; React precisa encontrar um nó dessa árvore para montar a interface.

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>clinica-vet</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

Duas linhas do <body> fazem o projeto inteiro funcionar. A div vazia com id="root" é o buraco onde o React vai despejar a interface. E o <script type="module"> carrega o src/main.jsx, que é quem faz o despejo:

jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

As quatro importações preparam o caminho. StrictMode vem do React; createRoot, da integração do React com o DOM; index.css entra pelos seus efeitos visuais; e App é o componente principal da tela. Importar significa usar algo exportado por outro módulo.

document.getElementById('root') procura no DOM o elemento cujo identificador é root. createRoot recebe esse elemento e cria uma raiz controlada pelo React. O .render() descreve o que entra nela. StrictMode é um modo de desenvolvimento que repete algumas verificações para revelar efeitos problemáticos; ele não adiciona essa repetição ao build de produção.

index.html <div id="root"> src/main.jsx createRoot(...).render() src/App.jsx <App /> o HTML entrega a div vazia; o React preenche

null representa ausência: a busca não encontrou elemento com aquele ID. O conserto é fazer os dois lados concordarem. Restaure id="root" no HTML ou use o novo identificador no getElementById, salve e atualize a página.

O erro é este, reproduzido no Node com jsdom simulando a página — a mensagem é a mesma que aparece no console do navegador. Se quiser rodar por conta própria, faça numa pasta separada, fora do projeto, com o que ele precisa instalado: npm init -y && npm pkg set type=module && npm i jsdom react react-dom.

js
import { JSDOM } from 'jsdom'
import { createRoot } from 'react-dom/client'

// o index.html do projeto foi editado e o id virou "app"
const pagina = new JSDOM('<!doctype html><body><div id="app"></div></body>')
globalThis.window = pagina.window
globalThis.document = pagina.window.document

createRoot(document.getElementById('root'))
/private/tmp/pata-serena/teste-root/node_modules/react-dom/cjs/react-dom-client.development.js:28014 throw Error("Target container is not a DOM element."); ^

Error: Target container is not a DOM element. at process.env.NODE_ENV.exports.createRoot (/private/tmp/pata-serena/teste-root/node_modules/react-dom/cjs/react-dom-client.development.js:28014:15) at file:///private/tmp/pata-serena/teste-root/montar.mjs:9:1 at ModuleJob.run (node:internal/modules/esm/module_job:439:25) at async node:internal/modules/esm/loader:633:26 at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)

Node.js v24.16.0

Como instalar as dependências e abrir o projeto?

Dentro da pasta criada, npm install baixa os pacotes registrados no package.json; depois, npm run dev inicia um servidor local para o navegador. O primeiro prepara a bancada, e o segundo liga essa bancada.

Instale as dependências:

bash
npm install
added 24 packages, and audited 25 packages in 6s

9 packages are looking for funding run npm fund for details

found 0 vulnerabilities

Vinte e quatro pacotes e 55 MB foram para node_modules. O npm também criou package-lock.json, que registra as versões exatas instaladas para outras máquinas repetirem a mesma árvore. “Audited” indica que o npm comparou os pacotes com sua base de vulnerabilidades conhecidas; não é uma garantia geral de segurança.

O tempo não se repete exatamente na sua máquina: depende da rede e do cache, uma cópia local que evita baixar novamente o que o npm já tem.

Experimente você mesmo: qual endereço o Vite vai escolher?

Antes de iniciar, anote sua previsão: a primeira tentativa deve usar a porta 5173. Uma porta é como uma entrada numerada do computador para um serviço. Se ela estiver ocupada, espere que o Vite imprima outro número. Agora suba o servidor:

bash
npm run dev
> clinica-vet@0.0.0 dev > vite

Port 5173 is in use, trying another one… Port 5174 is in use, trying another one…

VITE v8.2.2 ready in 83 ms

➜ Local: http://localhost:5175/ ➜ Network: use –host to expose

Duas coisas nessa saída. A primeira: 83 milissegundos para o servidor ficar de pé — o Vite não empacota o projeto para começar, ele serve cada arquivo sob demanda. A segunda: nesta máquina as portas 5173 e 5174 já estavam ocupadas, e o Vite subiu na 5175. Compare com sua previsão e abra a URL que o seu terminal imprimiu, não a que o tutorial diz. Local significa que esse endereço está disponível na sua própria máquina.

Como trocar o template por uma tela real?

Remova os arquivos usados apenas na demonstração e substitua App.jsx pela agenda. Assim, o esqueleto mínimo vira uma tela com dados do cotidiano.

Antes de escrever sua primeira linha, apague os recursos que não serão usados:

bash
rm -rf src/assets public/icons.svg

rm -rf apaga sem pedir confirmação. Confira se o terminal está dentro de clinica-vet e se os dois caminhos estão corretos antes de executá-lo.

Depois esvazie o src/App.css (ele só estiliza a tela de boas-vindas) e reduza o src/index.css ao mínimo:

css
:root {
  font-family: system-ui, sans-serif;
  line-height: 1.6;
}

body {
  margin: 0;
  padding: 2rem;
}

Agora src/App.jsx vira a agenda. Ele usa JSX, uma sintaxe parecida com HTML escrita dentro do JavaScript:

jsx
import './App.css'

const consultas = [
  { id: 1, hora: '08:30', pet: 'Amora', tutor: 'Renata', servico: 'Vacina V10' },
  { id: 2, hora: '09:15', pet: 'Thor', tutor: 'Marcelo', servico: 'Retorno' },
  { id: 3, hora: '10:00', pet: 'Nina', tutor: 'Juliana', servico: 'Castração' },
]

function App() {
  return (
    <main>
      <h1>Agenda de hoje</h1>
      <ul>
        {consultas.map((consulta) => (
          <li key={consulta.id}>
            {consulta.hora}{consulta.pet} ({consulta.tutor}): {consulta.servico}
          </li>
        ))}
      </ul>
    </main>
  )
}

export default App

consultas é um array (uma lista) de objetos; cada objeto reúne os dados de um horário. App é a função componente que retorna a interface. Dentro da lista, map percorre cada consulta e chama a callback, a função recebida entre parênteses, para criar um <li>. A prop key identifica cada item para o React; sem ela, o console avisa. Veja o motivo em listas com map e key.

Falta ajustar o index.html, que ainda está em inglês e com o título da pasta. Troque lang="en" por lang="pt-BR" e o <title> por algo que faça sentido — esse texto é o que aparece na aba do navegador e no resultado de busca.

Depois da limpeza sobram onze dos quinze arquivos do template — mais o package-lock.json, que o npm install escreveu. O README.md, o .gitignore e o .oxlintrc.json ficam: o primeiro você reescreve, os outros dois já estão prontos e corretos.

Como o Vite atualiza a tela sem recarregar a página?

Ele usa HMR (Hot Module Replacement, ou substituição de módulo a quente): envia somente o módulo alterado ao navegador enquanto o servidor continua de pé.

Com o npm run dev rodando, troque o texto do <h1> para Agenda de hoje na Pata Serena e salve. O terminal ganha uma linha na hora:

bash
# terminal do npm run dev, logo depois de salvar o App.jsx
7:29:46 PM [vite] (client) hmr update /src/App.jsx

O Vite enviou ao navegador só o módulo alterado, e o React trocou o componente. Em edições compatíveis, o React Refresh preserva até o estado, a memória temporária da tela; certas mudanças ainda exigem recarregá-la.

Para ver o mecanismo, peça ao servidor o mesmo arquivo que o navegador pede:

bash
curl -s http://localhost:5175/src/App.jsx
import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/src/App.jsx");const _jsxDEV = __vite__cjsImport1_react_jsxDevRuntime["jsxDEV"];import "/src/App.css"; var _jsxFileName = "/private/tmp/pata-serena/clinica-vet/src/App.jsx"; import __vite__cjsImport1_react_jsxDevRuntime from "/node_modules/.vite/deps/react_jsx-dev-runtime.js?v=2524d9c1"; const consultas = [ { id: 1, hora: "08:30", pet: "Amora", tutor: "Renata", servico: "Vacina V10" }, [… as outras duas consultas, no mesmo formato …] ]; function App() { return /* @__PURE__ */ _jsxDEV("main", { children: [/* @__PURE__ */ _jsxDEV("h1", { children: "Agenda de hoje na Pata Serena" }, void 0, false, { fileName: _jsxFileName, lineNumber: 12, columnNumber: 7 }, this), /* @__PURE__ */ _jsxDEV("ul", { children: consultas.map((consulta) => /* @__PURE__ */ _jsxDEV("li", { children: [ [… o resto do componente, e depois o bloco do React Refresh …]

Três descobertas numa resposta só. O <h1> já vem com o texto novo, sem reiniciar nada. O JSX não chegou ao navegador: virou chamadas de _jsxDEV, porque navegador nenhum entende JSX. E a primeira linha — aquela emenda comprida antes de qualquer código seu — injeta o createHotContext, que é o canal por onde a atualização quente viaja.

Como criar e conferir o build de produção?

Rode npm run build para gerar em dist/ os arquivos otimizados para publicação. Build é esse processo de transformar o código-fonte na versão que a hospedagem entrega:

bash
npm run build
vite v8.2.2 building client environment for production... transforming... ✓ 17 modules transformed. rendering chunks... computing gzip size... dist/index.html 0.47 kB │ gzip: 0.31 kB dist/assets/index-BL7ybgBW.css 0.08 kB │ gzip: 0.09 kB dist/assets/index-CZtxkWAz.js 190.77 kB │ gzip: 60.16 kB

✓ built in 295ms

O resultado é a pasta dist/, e é ela inteira que sobe para a hospedagem:

dist/assets/index-BL7ybgBW.css dist/assets/index-CZtxkWAz.js dist/favicon.svg dist/index.html

Quatro arquivos. O JavaScript tem 190,77 kB e cai para 60,16 kB com gzip, uma compressão usada na transferência. Quase todo esse peso vem do React; a agenda ocupa poucas centenas de bytes.

Os nomes com letras aleatórias no meio (index-CZtxkWAz.js) não são aleatórios: são um resumo do conteúdo do arquivo. Prove: acrescente esta quarta consulta ao array, exatamente assim, e rode o build de novo.

jsx
  { id: 4, hora: '11:30', pet: 'Fumaça', tutor: 'Beatriz', servico: 'Banho medicinal' },
bash
npm run build
dist/index.html 0.47 kB │ gzip: 0.31 kB dist/assets/index-BL7ybgBW.css 0.08 kB │ gzip: 0.09 kB dist/assets/index-CF_umR9A.js 190.85 kB │ gzip: 60.19 kB

✓ built in 91ms

O JavaScript mudou de nome (CZtxkWAz virou CF_umR9A) porque o conteúdo mudou. O CSS manteve o hash, porque não foi tocado. E as letras não são sorteadas a cada execução: elas saem do próprio conteúdo, então, com o App.jsx e o index.css iguais aos daqui, o seu build imprime esses mesmos dois nomes. É essa propriedade que permite ao navegador guardar os arquivos para sempre: quando você publica uma correção, o nome muda e o cache velho é ignorado sozinho.

O dist/index.html também foi reescrito — o <script src="/src/main.jsx"> some e entram as tags que apontam para os arquivos com hash:

bash
cat dist/index.html
<!doctype html> <html lang="pt-BR"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Pata Serena — agenda</title> <script type="module" crossorigin src="/assets/index-CF_umR9A.js"></script> <link rel="stylesheet" crossorigin href="/assets/index-BL7ybgBW.css"> </head> <body> <div id="root"></div> </body> </html>

O npm run preview abre um servidor local que entrega dist/ sem HMR. Ele serve para conferir o build antes de publicar, não para hospedar o site em produção:

bash
npm run preview
➜ Local: http://localhost:4173/ ➜ Network: use --host to expose

Como corrigir Node antigo e porta ocupada no Vite?

Confira primeiro a versão do Node; depois, use a URL exata mostrada pelo Vite. Essas duas checagens separam um problema do ambiente de um erro no seu código.

O primeiro erro aparece quando o runtime Node, o programa que executa as ferramentas JavaScript, é antigo demais. O Vite 8 exige ^20.19.0 || >=22.12.0, e o npm install avisa — só que o aviso passa despercebido no meio da instalação:

bash
npm install
npm warn EBADENGINE Unsupported engine { npm warn EBADENGINE package: 'vite@8.2.2', npm warn EBADENGINE required: { node: '^20.19.0 || >=22.12.0' }, npm warn EBADENGINE current: { node: 'v18.20.8', npm: '10.8.2' } npm warn EBADENGINE }

EBADENGINE significa que a versão do runtime não atende ao pacote. Como é warn e não error, a instalação termina; o npm run dev falha depois:

bash
npm run dev
file:///private/tmp/pata-serena/clinica-vet/node_modules/rolldown/dist/shared/create-bundler-option-Cj0juyCQ.mjs:8 import { formatWithOptions, styleText } from "node:util"; ^^^^^^^^^ SyntaxError: The requested module 'node:util' does not provide an export named 'styleText' at ModuleJob._instantiate (node:internal/modules/esm/module_job:123:21) at async ModuleJob.run (node:internal/modules/esm/module_job:191:5) at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)

Node.js v18.20.8

Traduzindo: uma ferramenta do Vite usa styleText, que só existe no Node 20.12 em diante. Não é bug do seu código nem do Vite — é o Node velho. A correção é atualizar, e o caminho sem dor é o nvm, que troca a versão do Node por projeto.

O segundo tropeço é a porta. Você já viu o Vite pulando de 5173 para 5175 sozinho, o que é ótimo — até você abrir a URL errada e jurar que o projeto não carregou. Para descobrir quem ocupou a porta:

bash
lsof -nP -iTCP:5173 -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 47557 rodolfomori 30u IPv6 0x5e960e5b9dedfa9b 0t0 TCP [::1]:5173 (LISTEN)

Um node de uma sessão anterior. PID é o identificador numérico do processo; encerre-o com kill 47557, trocando pelo PID da sua saída. Se o back-end aceita requisições de uma origem específica por CORS, uma regra do navegador, use --strictPort para o Vite falhar em vez de trocar a porta:

bash
npm run dev -- --port 5173 --strictPort
error when starting dev server: Error: Port 5173 is already in use at httpServerStart (file:///private/tmp/pata-serena/clinica-vet/node_modules/vite/dist/node/chunks/node.js:11681:10) at process.processTicksAndRejections (node:internal/process/task_queues:104:5) at async startServer (file:///private/tmp/pata-serena/clinica-vet/node_modules/vite/dist/node/chunks/node.js:26694:30) at async Object.listen (file:///private/tmp/pata-serena/clinica-vet/node_modules/vite/dist/node/chunks/node.js:26511:4) at async CAC.<anonymous> (file:///private/tmp/pata-serena/clinica-vet/node_modules/vite/dist/node/cli.js:721:3)

Falhar alto é melhor que subir na porta errada: assim você resolve agora, e não depois de meia hora depurando um CORS que nunca esteve quebrado.

O que aprender depois de criar o projeto React?

O próximo passo é entender melhor o JSX, o map e a key usados em App.jsx. A trilha de React conduz essa sequência; o guia de React mostra o mapa completo.

Até aqui: você criou o esqueleto com create-vite, instalou os pacotes, ligou HTML e React, trocou o template por uma agenda e gerou o build em dist/.

Antes de avançar, troque o título do App.jsx, salve e confirme a atualização por HMR. Depois rode npm run build e verifique que a pasta dist foi criada. Abra npm run preview e confira a mesma tela no build final. Esses três sinais — HMR, build sem erro e preview funcionando — confirmam que o projeto foi montado por inteiro, não apenas que o comando inicial criou uma pasta.

Prefere aprender em vídeo?

Tem uma aula sobre este assunto no nosso canal.

Ver todos os vídeos do canal
  • react
  • vite
  • npm
  • setup
  • projeto

Perguntas frequentes

Preciso instalar o Vite antes de criar o projeto?
Não. O npm create vite@latest baixa o create-vite na hora, gera a pasta e some. O Vite de verdade entra depois, como dependência de desenvolvimento do próprio projeto, quando você roda npm install.
Posso criar o projeto dentro de uma pasta que já existe?
Pode. Rode o comando com um ponto no lugar do nome (npm create vite@latest . -- --template react) e ele monta o projeto na pasta atual. Se ela já tiver arquivos, o assistente pergunta antes de sobrescrever.
Qual a diferença entre o template react e o react-ts?
Só a linguagem. O react gera arquivos .jsx com JavaScript puro; o react-ts gera .tsx, adiciona o tsconfig.json e liga a checagem de tipo. Dá para migrar depois, mas custa mais que escolher certo agora.
Dá para usar yarn ou pnpm em vez do npm?
Dá. Os equivalentes são yarn create vite e pnpm create vite. O projeto gerado é idêntico; muda só o arquivo de lock e o nome do comando que você digita para rodar os scripts.

Dúvidas e comentários

Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.

Todo o código deste artigo foi executado em Node 24.16.0 · Vite 8.2.2 · React 19.2.8, e as saídas exibidas são as reais — como produzimos este conteúdo.

Fontes consultadas

  1. Vite — Getting Started — vite.dev
  2. Vite — Building for Production — vite.dev
  3. React — Creating a React App — react.dev

Continue por aqui