Guía
React: Something is already running on port 3000. ¿Conviene decir que sí?
14 de septiembre de 20263 min de lectura
Create React App maneja esto distinto a cualquier otro servidor de desarrollo. No falla, y no se cambia en silencio. Pregunta:
? Something is already running on port 3000.
Would you like to run the app on another port instead? (Y/n)
El default es sí, así que apretar Enter lo acepta. Normalmente esa es la respuesta equivocada, y vale la pena saber por qué antes de que se te haga costumbre.
Por qué decir que sí esconde el problema
Aceptas, y tu app abre en el 3001 mientras lo que está en el 3000 sigue corriendo. No resolviste nada, lo rodeaste. Haz eso unas cuantas veces en unos días y acumulas servidores huérfanos en el 3000, 3001, 3002, cada uno ocupando memoria y cada uno invisible.
Peor todavía, cualquier cosa configurada para localhost:3000 ahora apunta a la app equivocada. Un callback de OAuth, un proxy en el package.json, una API simulada. La falla aparece después como un login que no funciona, y no la vas a conectar con una pregunta que despachaste el martes.
Responde n y averigua qué hay realmente en el 3000. Toma diez segundos.
Encontrarlo
lsof -i :3000
Si es un proceso node, casi con certeza es tu propia corrida anterior:
lsof -ti :3000 | xargs kill
-t imprime solo los IDs de proceso, xargs se los pasa todos a un solo kill, y un kill normal manda SIGTERM para que el proceso salga limpio. Usa -9 solo si lo ignora.
Fijar el puerto como corresponde
Si genuinamente quieres otro puerto, configúralo en vez de responder una pregunta cada vez.
PORT=3001 npm start
O de forma permanente, en un archivo .env en la raíz del proyecto:
PORT=3001
CRA lee PORT del entorno, así que esto sobrevive a los reinicios y aplica para todos en el proyecto. Mucho mejor que una pregunta que nadie lee.
Una nota sobre Create React App
Si estás partiendo algo nuevo en 2026, CRA ya no es la recomendación por defecto y hace rato que no lo es. La mayoría de los proyectos nuevos de React usan Vite o Next.js, los dos más rápidos y con mantención activa.
Importa acá porque el comportamiento cambia. Vite se cambia en silencio al siguiente puerto y Next.js hace lo mismo, ninguno de los dos pregunta. Si migras, la pregunta desaparece y toma su lugar el cambio silencioso, que tiene su propia trampa.
Cuando el puerto lo ocupa algo que no es Node
Dos casos aparecen seguido.
Docker. Un contenedor publicando el 3000 aparece como docker-proxy. Matarlo no sirve de nada, Docker lo vuelve a publicar de inmediato:
docker ps --filter "publish=3000"
docker stop <contenedor>
Otro framework. Rails, Next.js y varios más también usan el 3000 por defecto. Si tienes dos proyectos abiertos, están compitiendo por él por diseño. Dale a cada uno un puerto fijo y distinto y los choques se acaban.
Cuando nada escucha pero igual pregunta
Si lsof -i :3000 no imprime nada y aun así te pregunta, el puerto está en TIME_WAIT, un estado de TCP que reserva un puerto recién cerrado por unos treinta segundos. No hay proceso que matar, así que esperar es el arreglo.
Los detalles en qué significa realmente EADDRINUSE.
Bosun lista qué hay en cada puerto desde la barra de menú, así responder esa pregunta pasa a ser una decisión y no una adivinanza. macOS 14 o posterior, prueba de 14 días.
Ve esto en vez de escribirlo
Bosun vive en tu barra de menú y muestra cada puerto abierto en tu Mac, en vivo, mapeado al proceso detrás. Un clic para matarlo, SIGTERM primero. Útil la primera vez que pasa esto. Realmente útil la quinta vez que pasa en una misma tarde.