Trabajar con React en serio requiere un pequeño ecosistema de herramientas: un entorno de ejecución de JavaScript fuera del navegador (Node.js), un gestor de paquetes (npm), una herramienta de construcción que transforme tu código y te dé un servidor de desarrollo rápido (Vite), un editor bien configurado y una extensión de navegador para inspeccionar componentes. En esta lección montarás ese entorno de principio a fin y crearás el proyecto CicloUrbano que usarás durante todo el curso. Al terminar tendrás una aplicación funcionando en tu navegador y entenderás qué hace cada fichero generado.

Contenido

  1. Requisitos previos: Node.js y npm
  2. El editor y sus extensiones
  3. Crear el proyecto de CicloUrbano con Vite
  4. Recorrido por la estructura de carpetas
  5. Los scripts de npm: dev, build, preview
  6. Recarga en caliente (Hot Module Replacement)
  7. React DevTools en el navegador
  8. Por qué Vite y no Create React App

  1. Requisitos previos: Node.js y npm

React se escribe con una sintaxis (JSX) que los navegadores no entienden directamente y se distribuye en paquetes que hay que descargar. Ambas cosas necesitan Node.js, el entorno que permite ejecutar JavaScript fuera del navegador, y npm (Node Package Manager), que se instala junto con Node.

Qué versión instalar

Usa siempre una versión LTS (Long Term Support): son las versiones pares (20, 22, 24...) con soporte prolongado y las que las herramientas dan por buenas. Vite requiere Node 20.19 o superior. Descárgala de nodejs.org o, mejor aún, instala un gestor de versiones como nvm (macOS/Linux) o fnm (multiplataforma), que te permite tener varias versiones y cambiar entre ellas por proyecto.

Comprobar que todo está en su sitio

Abre una terminal y ejecuta:

node --version
npm --version

Salida esperada (los números concretos variarán, pero el formato es este):

v22.14.0
10.9.2

Si el comando no se reconoce, Node no está instalado o no está en el PATH; reinicia la terminal tras instalarlo. Si la versión de Node es inferior a 20, actualízala antes de continuar: verás errores confusos más adelante.

Un apunte sobre gestores de paquetes

Gestor Comando de instalación Notas
npm npm install Viene con Node. Es el que usaremos en todo el curso
pnpm pnpm install Más rápido y ahorra disco al compartir dependencias entre proyectos
yarn yarn Alternativa histórica, aún muy usada en proyectos existentes

Los tres resuelven el mismo problema y los comandos son casi intercambiables. Usaremos npm porque no requiere instalar nada extra.

  1. El editor y sus extensiones

El editor recomendado es Visual Studio Code, gratuito y con el mejor soporte para React. Estas extensiones aportan una mejora real en el día a día:

Extensión Para qué sirve
ESLint Marca errores y malas prácticas mientras escribes (hooks mal usados, variables sin utilizar, key que faltan)
Prettier Formatea el código automáticamente al guardar: se acaban las discusiones sobre comillas e indentación
ES7+ React/Redux/React-Native snippets Atajos como rafce que generan el esqueleto de un componente de función
Auto Rename Tag Al renombrar una etiqueta de apertura en JSX, renombra la de cierre
Error Lens Muestra el mensaje de error en la propia línea, sin tener que pasar el ratón por encima

Una configuración muy recomendable es activar el formateo al guardar. En VS Code, Ctrl+, → busca «format on save» → márcalo. O directamente en .vscode/settings.json dentro del proyecto:

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  }
}

  1. Crear el proyecto de CicloUrbano con Vite

Vite (se pronuncia «vit», rápido en francés) es la herramienta de construcción estándar hoy para proyectos React. Hace dos cosas: durante el desarrollo levanta un servidor casi instantáneo que sirve tu código, y para producción genera los ficheros optimizados que subirás al hosting.

Sitúate en la carpeta donde guardes tus proyectos y ejecuta:

npm create vite@latest ciclourbano -- --template react

Desmenucemos ese comando, porque los guiones dobles confunden a mucha gente:

  • npm create vite@latest descarga y ejecuta el asistente de creación de Vite en su última versión, sin instalarlo permanentemente.
  • ciclourbano es el nombre de la carpeta del proyecto.
  • El -- separa los argumentos de npm de los argumentos del asistente. Sin él, npm intentaría interpretar --template como una opción suya.
  • --template react elige la plantilla de React con JavaScript. (Si quisieras TypeScript sería react-ts; lo verás en la lección 10-04, pero en este curso usamos JavaScript).

Salida esperada:

Scaffolding project in /home/tu-usuario/proyectos/ciclourbano...

Done. Now run:

  cd ciclourbano
  npm install
  npm run dev

Sigue esas tres instrucciones:

cd ciclourbano
npm install

npm install lee package.json, descarga las dependencias a la carpeta node_modules/ y crea package-lock.json. Tarda entre unos segundos y un minuto según tu conexión:

added 152 packages, and audited 153 packages in 12s
found 0 vulnerabilities

Y arranca el servidor de desarrollo:

npm run dev
  VITE v7.0.0  ready in 187 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

Abre http://localhost:5173/ en el navegador: verás la página de bienvenida de Vite + React con un contador. Deja este proceso corriendo en su terminal mientras trabajas; para detenerlo, Ctrl+C.

Si el puerto 5173 está ocupado, Vite usará el 5174, el 5175, etc. Fíjate siempre en la URL que imprime la consola.

  1. Recorrido por la estructura de carpetas

Esto es lo que Vite ha generado:

ciclourbano/
├── node_modules/          <- dependencias descargadas (nunca se toca ni se sube a git)
├── public/                <- ficheros estáticos servidos tal cual
│   └── vite.svg
├── src/                   <- TU código: aquí trabajarás siempre
│   ├── assets/
│   │   └── react.svg
│   ├── App.css
│   ├── App.jsx            <- componente raíz de la aplicación
│   ├── index.css          <- estilos globales
│   └── main.jsx           <- punto de entrada de JavaScript
├── .gitignore
├── eslint.config.js
├── index.html             <- página HTML real que sirve el navegador
├── package.json
├── package-lock.json
├── README.md
└── vite.config.js

index.html: el punto de partida real

En un proyecto Vite, el HTML no está escondido dentro de la configuración: es un fichero de primer nivel y es el verdadero punto de entrada.

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

Dos líneas son las importantes:

  • <div id="root"></div> es el contenedor vacío donde React montará toda la aplicación. Todo lo que verás en pantalla acabará dentro de ese div.
  • <script type="module" src="/src/main.jsx"> carga tu código como módulo ES. Es el hilo que enlaza el HTML con React.

Aprovecha para personalizarlo ahora, ya que es tu proyecto:

<html lang="es">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CicloUrbano — Alquiler de bicicletas urbanas</title>
  </head>

src/main.jsx: donde arranca React

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>
);

Es el fichero que conecta React con el div#root del HTML. Lo analizaremos línea a línea en la siguiente lección; por ahora quédate con que aquí empieza todo.

El resto de piezas

Fichero / carpeta Para qué sirve
src/App.jsx Componente raíz. De él cuelga el árbol completo de componentes de CicloUrbano
src/index.css Estilos globales: tipografía base, colores, reinicio de márgenes
src/App.css Estilos del componente App (en el Módulo 2 verás mejores estrategias)
src/assets/ Imágenes y recursos que importas desde el código; Vite los optimiza y les añade un hash al construir
public/ Recursos servidos tal cual, sin procesar, en la raíz del sitio: public/logo.png se sirve como /logo.png. Úsala para favicon.ico, robots.txt o descargas
package.json Nombre del proyecto, dependencias y scripts ejecutables
package-lock.json Versiones exactas instaladas. Se sube a git para que todo el equipo instale lo mismo
vite.config.js Configuración de Vite (plugins, alias, puerto, proxy)
eslint.config.js Reglas de análisis estático del código
.gitignore Lista de lo que git debe ignorar; incluye node_modules/ y dist/
node_modules/ Dependencias descargadas. Pesa mucho, se regenera con npm install y nunca se sube a git

Diferencia clave entre src/assets/ y public/: lo que está en assets pasa por el proceso de construcción (se optimiza, se renombra con un hash para cachear bien y, si no se usa, se elimina); lo que está en public se copia sin tocar y su nombre no cambia.

vite.config.js

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()]
});

Es mínimo a propósito. El plugin @vitejs/plugin-react es el que enseña a Vite a transformar JSX y el que habilita la recarga en caliente de componentes. Si más adelante necesitas un alias de rutas o un proxy hacia una API, se configura aquí.

Cómo encajan las piezas

flowchart TD
    A[Navegador pide index.html] --> B["index.html contiene div#root<br/>y carga /src/main.jsx"]
    B --> C[main.jsx: createRoot + render]
    C --> D[App.jsx: componente raíz]
    D --> E[Componentes de CicloUrbano<br/>src/componentes/]
    F[Vite: servidor de desarrollo] -.transforma JSX al vuelo.-> B

  1. Los scripts de npm: dev, build, preview

Ábrelo tú mismo, package.json:

{
  "name": "ciclourbano",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^19.1.0",
    "react-dom": "^19.1.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.4.0",
    "eslint": "^9.25.0",
    "vite": "^7.0.0"
  }
}
Script Comando Qué hace Cuándo lo usas
dev npm run dev Levanta el servidor de desarrollo con recarga en caliente en localhost:5173 Todo el rato mientras programas
build npm run build Genera la versión de producción optimizada en dist/ Antes de desplegar
preview npm run preview Sirve localmente lo que hay en dist/ para comprobarlo Después de build, para validar antes de subir
lint npm run lint Analiza el código en busca de errores y malas prácticas Antes de confirmar cambios en git

Prueba el ciclo completo ahora:

npm run build
vite v7.0.0 building for production...
✓ 34 modules transformed.
dist/index.html                   0.46 kB │ gzip:  0.30 kB
dist/assets/index-DiwrgTda.css    1.39 kB │ gzip:  0.72 kB
dist/assets/index-C9n2Xk4p.js   143.41 kB │ gzip: 46.12 kB
✓ built in 612 ms
npm run preview
  ➜  Local:   http://localhost:4173/

Observa dos detalles importantes: preview usa un puerto distinto (4173) para que no lo confundas con el de desarrollo, y los ficheros de dist/ llevan un hash en el nombre (index-C9n2Xk4p.js). Ese hash cambia cuando cambia el contenido, lo que permite al navegador cachear agresivamente sin servir nunca una versión antigua.

Sobre dependencies frente a devDependencies: las primeras acaban en el paquete que llega al navegador (react, react-dom); las segundas solo se usan en tu máquina para construir y analizar el código (vite, eslint). Por eso el resultado de build pesa mucho menos que node_modules/.

  1. Recarga en caliente (Hot Module Replacement)

El HMR (Hot Module Replacement, sustitución de módulos en caliente) es la razón por la que el desarrollo con Vite resulta tan cómodo. Cuando guardas un fichero, Vite no recarga la página entera: envía por WebSocket solo el módulo que ha cambiado y React lo sustituye en vivo.

La diferencia práctica es enorme:

Recarga completa HMR
Tiempo hasta ver el cambio 1-3 segundos Decenas de milisegundos
Estado de la aplicación Se pierde: vuelves al inicio Se conserva
Scroll y foco Se reinician Se mantienen

El «estado se conserva» es lo que más agradecerás: si has rellenado medio formulario de reserva de CicloUrbano y ajustas un color en el CSS, sigues viendo el formulario relleno.

Pruébalo. Con npm run dev corriendo, abre src/App.jsx, cambia cualquier texto visible y guarda. El navegador se actualiza solo, sin parpadeo. En la consola de Vite verás:

9:41:23 [vite] hmr update /src/App.jsx

Hay casos en que el HMR no puede aplicar el cambio y recarga la página entera: al modificar vite.config.js, al tocar index.html, o cuando cambias la estructura de un módulo de forma que Vite no puede reconciliar. Es normal.

  1. React DevTools en el navegador

React DevTools es la extensión oficial que permite inspeccionar tu aplicación en términos de React —componentes, props, estado— en lugar de en términos de nodos HTML.

Instalación

  • Chrome / Edge: busca «React Developer Tools» en Chrome Web Store e instálala.
  • Firefox: búscala en addons.mozilla.org.
  • Safari u otros: se puede usar la versión independiente con npx react-devtools.

Tras instalarla, abre http://localhost:5173, pulsa F12 y verás dos pestañas nuevas: Components y Profiler.

Qué muestra la pestaña Components

  • El árbol de componentes con sus nombres reales (App, ListaBicicletas, TarjetaBicicleta), en vez de una maraña de div. Esta es la razón principal para instalarla.
  • Props y estado del componente seleccionado, en el panel derecho, y editables al vuelo para probar casos sin tocar el código.
  • El componente padre que lo renderiza y la ruta completa hasta la raíz.
  • Un selector (icono de flecha) para pinchar un elemento de la página y saltar a su componente.

Comprueba que funciona: abre Components y verás App en el árbol, y dentro de él StrictMode. Todavía hay poco que ver, pero a partir de la lección 01-03 esta pestaña será tu herramienta de diagnóstico principal.

La pestaña Profiler mide el rendimiento de los renders. Es una herramienta excelente, pero requiere entender antes cómo renderiza React; se estudia en la lección Medir el Rendimiento con React DevTools Profiler.

  1. Por qué Vite y no Create React App

Durante años, la forma estándar de crear un proyecto React fue create-react-app (CRA). Hoy no debes usarlo:

  • Está descontinuado. La documentación oficial de React lo retiró de sus recomendaciones en 2023 y el paquete dejó de mantenerse activamente. Instalarlo hoy muestra avisos de dependencias obsoletas.
  • Es lento. CRA usa webpack con Babel y empaqueta toda la aplicación antes de poder servir nada: arrancar un proyecto mediano podía llevar 30 segundos o más, y cada cambio varios segundos. Vite sirve los módulos ES nativamente y usa esbuild (escrito en Go) para las dependencias: arranca en menos de un segundo con independencia del tamaño del proyecto.
  • Es opaco. Su configuración está escondida tras react-scripts, y personalizarla obligaba a eject (una operación irreversible que vuelca cientos de líneas de configuración en tu repositorio) o a parches externos. vite.config.js son cinco líneas legibles.
Create React App Vite
Estado Descontinuado Activo y estándar de facto
Arranque del servidor Decenas de segundos Menos de un segundo
Actualización tras un cambio Segundos Milisegundos
Configuración Oculta; eject irreversible Fichero corto y editable
Construcción de producción webpack Rollup, con división de código incluida

Que CRA aparezca en tutoriales antiguos es la mejor señal para desconfiar de su actualidad: si un tutorial usa create-react-app, probablemente también use componentes de clase y APIs anteriores a los hooks. Menciónalo solo como contexto histórico.

Errores Comunes y Consejos

  • Ejecutar npm run dev fuera de la carpeta del proyecto. Da npm error Missing script: "dev". Comprueba con pwd (o ls package.json) que estás dentro de ciclourbano/.
  • Olvidar el -- en el comando de creación. npm create vite@latest ciclourbano --template react no pasa la plantilla al asistente y este te preguntará interactivamente. No es un error grave, pero conviene saber por qué ocurre.
  • Subir node_modules/ a git. Son decenas de miles de ficheros. El .gitignore que genera Vite ya lo excluye; no lo borres. Si alguien clona el repositorio, con npm install lo reconstruye.
  • Editar ficheros dentro de node_modules/. Cualquier cambio ahí desaparecerá en la siguiente instalación. Si necesitas modificar una dependencia, existen herramientas específicas (patch-package), pero casi nunca es la solución correcta.
  • Node en una versión demasiado antigua. Es la causa número uno de errores incomprensibles al instalar o arrancar. Verifica siempre node --version antes de pedir ayuda.
  • Cerrar la terminal donde corre npm run dev y esperar que la web siga funcionando. El servidor de desarrollo es ese proceso; si lo matas, localhost:5173 deja de responder.
  • Confundir el puerto de dev con el de preview. 5173 sirve tu código en desarrollo, 4173 sirve el contenido de dist/. Si editas y no ves cambios, comprueba en qué puerto estás.
  • Consejo: añade el proyecto a git desde el primer día (git init, git add ., git commit -m "Proyecto inicial de CicloUrbano"). Poder volver a un punto que funcionaba vale oro mientras aprendes.

Ejercicios

Ejercicio 1

Crea el proyecto de CicloUrbano siguiendo los pasos de la lección y, a continuación:

  1. Cambia el <title> de index.html a CicloUrbano — Alquiler de bicicletas urbanas y el atributo lang a es.
  2. Con el servidor de desarrollo en marcha, modifica cualquier texto de src/App.jsx y comprueba que el cambio aparece sin recargar la página.
  3. Ejecuta la construcción de producción y sírvela localmente. Anota qué puerto usa y qué tamaño tiene el fichero JavaScript generado.

Ejercicio 2

Clasifica cada uno de estos ficheros o carpetas en una de tres categorías: (A) lo edito habitualmente, (B) existe pero casi nunca lo toco, (C) nunca lo edito a mano.

src/App.jsx · node_modules/ · package.json · package-lock.json · index.html · vite.config.js · src/componentes/ · dist/

Ejercicio 3

Coloca dos imágenes en el proyecto: logo-ciclourbano.svg en public/ y bicicleta-urbana.svg en src/assets/. Explica con qué ruta referenciarías cada una y qué le pasa a cada fichero al ejecutar npm run build.

Soluciones

Solución 1.

npm create vite@latest ciclourbano -- --template react
cd ciclourbano
npm install
npm run dev

Edita index.html:

<html lang="es">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CicloUrbano — Alquiler de bicicletas urbanas</title>
  </head>

Al guardar src/App.jsx con un texto distinto, el navegador se actualiza en milisegundos sin perder el estado (si habías pulsado el contador de ejemplo, mantiene su valor): eso es el HMR en acción. La consola de Vite imprime [vite] hmr update /src/App.jsx.

Para el tercer punto:

npm run build
npm run preview

preview sirve en http://localhost:4173/. El fichero JavaScript rondará los 140-150 kB (unos 45 kB comprimidos con gzip), que es esencialmente el peso de React y React DOM.

Solución 2.

Fichero / carpeta Categoría Motivo
src/App.jsx A Es tu componente raíz; lo tocas constantemente
src/componentes/ A Aquí vivirán todos los componentes de CicloUrbano
package.json B Se modifica al añadir scripts; las dependencias las gestiona npm install
index.html B Título, idioma, favicon y metadatos; después casi no se toca
vite.config.js B Solo cuando necesites un alias, un proxy o un plugin
node_modules/ C Generada por npm; cualquier cambio se pierde
package-lock.json C Lo gestiona npm; se confirma en git pero no se edita a mano
dist/ C Salida de npm run build; se regenera y ni siquiera se sube a git

Solución 3.

  • public/logo-ciclourbano.svg se sirve tal cual desde la raíz del sitio. Se referencia con una ruta absoluta y su nombre no cambia nunca:

    <img src="/logo-ciclourbano.svg" alt="CicloUrbano" />
    

    Tras npm run build aparece en dist/logo-ciclourbano.svg con el mismo nombre. Es la opción correcta cuando la ruta debe ser estable y predecible (favicon, robots.txt, imágenes referenciadas desde fuera).

  • src/assets/bicicleta-urbana.svg se importa desde el código:

    import bicicletaUrbana from './assets/bicicleta-urbana.svg';
    
    <img src={bicicletaUrbana} alt="Bicicleta urbana" />
    

    Al construir, Vite lo procesa, lo renombra con un hash (dist/assets/bicicleta-urbana-B7kX2p1q.svg) y sustituye la referencia. Ventajas: caché óptima en el navegador, error en tiempo de construcción si la ruta está mal escrita, y eliminación automática si el fichero deja de usarse.

Conclusión

Ya tienes un entorno de desarrollo profesional: Node.js LTS y npm verificados, un editor con ESLint y Prettier, el proyecto CicloUrbano creado con Vite, el servidor de desarrollo corriendo con recarga en caliente y React DevTools instalado en el navegador. También sabes qué hace cada fichero generado, en qué se diferencian src/assets/ y public/, para qué sirve cada script de npm y por qué Vite ha sustituido a Create React App.

Hasta ahora solo has ejecutado código ajeno. En la siguiente lección, Hola Mundo en React, limpiarás la plantilla de ejemplo, entenderás línea a línea cómo main.jsx monta la aplicación en el DOM y escribirás tus dos primeros componentes propios: Bienvenida y TarjetaBicicleta.

Curso de React

Módulo 1: Introducción a React

Módulo 2: Componentes de React

Módulo 3: Trabajando con Eventos

Módulo 4: Conceptos Avanzados de Componentes

Módulo 5: Hooks de React

Módulo 6: Enrutamiento en React

Módulo 7: Gestión del Estado

Módulo 8: Optimización del Rendimiento

Módulo 9: Pruebas en React

Módulo 10: Temas Avanzados

Módulo 11: Proyecto: Construyendo una Aplicación Completa

© Copyright 2026. Todos los derechos reservados