¿Por qué tu build funciona en local pero falla en el deploy?
El build pasa en tu máquina pero falla en el servidor. Te explicamos las 10 causas más comunes —variables de entorno, mayúsculas, versiones, .gitignore— y cómo resolver cada una.

Por qué tu build funciona en local pero falla en el deploy (y cómo solucionarlo)
Respuesta corta: casi siempre es un problema de paridad de entornos: tu máquina y el servidor de build no son idénticos. Las causas más frecuentes son variables de entorno que existen en tu equipo pero no en el servidor, dependencias que tienes instaladas globalmente o como
devDependencies, diferencias de versión de Node/Python, archivos bloqueados por.gitignore, y la sensibilidad a mayúsculas de Linux (tu Mac o Windows perdona errores de mayúsculas en los imports; el servidor no). La solución pasa por reproducir el entorno de producción localmente y eliminar las suposiciones implícitas.
La causa raíz: "en mi máquina funciona"
El build que pasa en tu laptop y falla en el servidor es uno de los problemas más viejos y frecuentes del desarrollo. La razón de fondo es siempre la misma: tu entorno local y el de build no son iguales. Tu máquina acumula configuración, variables, dependencias globales y rutas que diste por sentadas, y el servidor arranca limpio.
Diagnosticar esto es un proceso de eliminar diferencias una por una. Estas son las que explican la gran mayoría de los casos.
1. Variables de entorno que existen solo en tu máquina
Tienes una variable en tu .env local o exportada en tu shell, y el código la usa durante el build. En el servidor no está definida, y el build falla o produce un artefacto roto.
Cómo diagnosticarlo: busca en tu código toda lectura de process.env. (Node) u os.environ (Python) que ocurra en tiempo de build.
Cómo solucionarlo: declara explícitamente cada variable en la configuración del entorno de deploy. Nunca subas el .env al repositorio; en su lugar documenta las variables requeridas en un .env.example versionado.
# .env.example (este SÍ se versiona; el .env real no)
DATABASE_URL=
API_KEY=
NODE_ENV=production
2. NODE_ENV=production cambia el comportamiento
Muchas apps de Node ejecutan lógica distinta según NODE_ENV. Un bug puede aparecer solo cuando ese valor es production —por ejemplo, al construir assets o comprimir imágenes— y nunca verse en desarrollo.
Cómo solucionarlo: reproduce el bug localmente forzando el mismo valor antes de buildear.
NODE_ENV=production npm run build
Si falla igual que en el servidor, ya tienes el caso aislado en tu máquina.
3. La dependencia está en devDependencies, no en dependencies
Tu build necesita un paquete (un bundler, un compilador de TypeScript, etc.), pero está listado en devDependencies. Muchas plataformas instalan solo dependencies en producción, así que el paquete nunca llega y el build truena con "command not found" o "module not found".
Cómo solucionarlo: mueve a dependencies todo lo que se necesite durante el build. Deja en devDependencies solo lo que uses para desarrollar y testear localmente.
npm install --save typescript # pasa de dev a dependency
4. Sensibilidad a mayúsculas: Linux no perdona
Este es el clásico silencioso. macOS y Windows usan sistemas de archivos que ignoran mayúsculas/minúsculas, así que import Button from './components/button' funciona aunque el archivo se llame Button.tsx. El servidor de build corre Linux, que sí distingue mayúsculas, y ese mismo import falla con "module not found".
Cómo diagnosticarlo: revisa que cada ruta de import coincida exactamente —carácter por carácter— con el nombre real del archivo y la carpeta.
Cómo solucionarlo: corrige los imports para que coincidan con el nombre exacto del archivo. Para prevenirlo a futuro, activa la verificación de mayúsculas en tu bundler o linter.
5. Versión de Node, Python o del runtime distinta
Tú corres una versión local; el servidor usa otra por defecto. Una API que existe en tu versión puede no existir en la del build, o al revés.
Cómo solucionarlo: fija la versión explícitamente en el proyecto para que el servidor use la misma.
// package.json{ "engines": { "node": "22.x" }}
# .python-version o runtime.txt según la plataforma
3.12
Verifica tu versión local con node --version o python --version y haz que coincidan.
6. Un archivo necesario está bloqueado por .gitignore
El archivo existe en tu disco pero una regla demasiado amplia del .gitignore impide que entre al repositorio. Como el build parte del repo, el archivo simplemente no está.
Ejemplo clásico: una regla lib ignora recursivamente cualquier carpeta llamada lib, incluyendo una que tu app necesita dentro de node_modules de un paquete propio o en tu código.
Cómo solucionarlo: ancla la regla a la raíz con una barra inicial para que solo aplique a la carpeta del nivel superior.
# Antes: ignora todas las carpetas "lib" en cualquier nivel
lib
# Después: ignora solo /lib en la raíz del proyecto
/lib
Confirma qué se está versionando realmente con git ls-files | grep <archivo>.
7. Lockfile desactualizado o sin commitear
Si tu package-lock.json, yarn.lock o poetry.lock no está commiteado o está desincronizado con el package.json, el servidor puede resolver versiones distintas a las tuyas y romper el build.
Cómo solucionarlo: versiona siempre el lockfile e instala con el comando que respeta el lock exacto.
npm ci # instala exactamente lo del lockfile (no lo modifica)
# en lugar de:
npm install # puede actualizar versiones
8. Dependencias nativas o herramientas de compilación ausentes
Algunos paquetes compilan código nativo (C/C++) durante la instalación y requieren herramientas de build (gcc, make, python) que tu máquina tiene pero la imagen del servidor no.
Cómo solucionarlo: revisa los logs del build para identificar el paquete que falla y asegúrate de que la imagen base incluya las herramientas de compilación necesarias, o usa una versión precompilada del paquete cuando exista.
9. El build se queda sin memoria
En local tienes 16 o 32 GB de RAM; el servidor de build puede tener mucho menos. Builds grandes (especialmente de frontend) mueren con un error de memoria que jamás verías localmente.
Cómo diagnosticarlo: busca en los logs mensajes como "JavaScript heap out of memory" o que el proceso muera sin razón aparente (señal de OOM).
Cómo solucionarlo: reduce el consumo del build (divide bundles, limita la concurrencia) o sube el límite de memoria del proceso si la plataforma lo permite.
NODE_OPTIONS=--max-old-space-size=4096 npm run build
10. Variables necesarias en build-time que no llegan al build
Distinto del punto 1: algunas plataformas inyectan las variables solo en runtime (cuando la app corre), no durante el build. Si tu compilación necesita una variable —por ejemplo, una URL pública de API para frontend— y solo está disponible en runtime, el build usará un valor vacío.
Cómo solucionarlo: confirma en la documentación de tu plataforma qué variables están disponibles en build-time y declara explícitamente las que necesite el proceso de compilación en esa fase.
Checklist de diagnóstico rápido
Cuando un build pase en local y falle en el deploy, recórrelo en este orden:
- ¿Reproduces el fallo con
NODE_ENV=production npm run builden local? - ¿Todas las variables de entorno del build están declaradas en el servidor?
- ¿Las dependencias del build están en
dependencies, no endevDependencies? - ¿Los imports coinciden exactamente en mayúsculas con los nombres de archivo?
- ¿La versión de Node/Python está fijada y coincide con la local?
- ¿Hay archivos necesarios bloqueados por
.gitignore? - ¿El lockfile está commiteado y usas
npm ci? - ¿Los logs mencionan memoria, herramientas de compilación o un paquete nativo?
El 95% de los casos se resuelve en uno de estos ocho puntos.
Preguntas frecuentes
¿Por qué mi import funciona en Mac pero falla en el servidor? Porque macOS y Windows ignoran mayúsculas en los nombres de archivo, pero Linux —que corre en el servidor— sí las distingue. Un import como ./Button no encontrará un archivo llamado button.tsx. Corrige la ruta para que coincida exactamente.
¿Cuál es la diferencia entre npm install y npm ci en un deploy? npm install puede actualizar versiones y modificar el lockfile; npm ci instala exactamente lo que dice el lockfile y falla si está desincronizado. Para builds reproducibles en deploy, usa siempre npm ci.
¿Por qué el build se queda sin memoria solo en el servidor? Tu máquina local suele tener mucha más RAM que el entorno de build. Builds grandes superan el límite del servidor y mueren con "heap out of memory". Reduce el tamaño del build o ajusta el límite de memoria del proceso.
¿Debo subir mi archivo .env al repositorio para que el deploy funcione? No. Nunca versiones el .env real. Declara las variables en la configuración de tu plataforma de deploy y versiona solo un .env.example sin valores como documentación.
Checklist rápido antes de investigar un build fallido
Cuando un build falla solo en el servidor, la tentación es revisar el código. Pero en la mayoría de los casos el código está bien: el problema está en lo que el código asume del entorno. Esta lista cubre las verificaciones que resuelven más del 80 % de estos incidentes sin necesidad de debuggear lógica de aplicación.
Recorre cada punto en orden. Si llegas al final sin encontrar la causa, lo más probable es que tengas una dependencia global implícita o un script de build distinto al que usas localmente.
- 1Compara variables de entornoCruza tu .env local con las variables configuradas en la plataforma de CI/deploy. Presta especial atención a las que se leen en tiempo de build, no solo en runtime.
- 2Verifica el archivo de lockAsegúrate de que package-lock.json, yarn.lock o equivalente está versionado y no está en .gitignore. Sin él, las versiones exactas de dependencias no son deterministas.
- 3Revisa la capitalización de importsSi el servidor usa Linux y tu máquina macOS o Windows, cualquier diferencia de mayúsculas en rutas de import causará fallo. Usa un linter que detecte esto automáticamente.
- 4Confirma que devDependencies no se usan en buildSi tu bundler o compilador vive en devDependencies y el servidor hace npm install sin --include=dev, la herramienta no existirá en el entorno de build.
- 5Fija la versión de runtimeEspecifica la versión exacta de Node o Python en tu configuración de CI (por ejemplo, con .nvmrc o engines en package.json) y usa la misma localmente.
~80%
Cobertura de este checklist
Estas 5 verificaciones resuelven la gran mayoría de fallos de build por diferencia de entornos según incidentes reportados en equipos de producto.
< 5 min
Tiempo medio de diagnóstico
Si tienes acceso a los logs y a la configuración del entorno de deploy, recorrer esta lista suele bastar para identificar la causa.
Recursos para profundizar
C4C7OPS
Elimina la sorpresa en tus deploys
C4C7OPS reproduce automáticamente el entorno de build, valida variables de entorno antes de ejecutar y te muestra exactamente qué difiere respecto a tu local. Sin más 'en mi máquina funciona'.
Cierra la brecha entre local y producción
Cada vez que un build falla solo en el servidor, estás pagando el costo de una suposición no documentada: una variable que solo existía en tu shell, una dependencia global que instalaste hace meses y olvidaste, o un import que tu sistema de archivos perdonó. La paridad de entornos no es un lujo, es la línea base para que los deploys sean predecibles.
El objetivo no es que tu servidor se parezca a tu máquina, sino que ambos se comporten idénticos a partir de la misma definición explícita: versiones fijadas, variables declaradas, archivos sin ambigüedades.
- 1Borra node_modules y ejecuta el buildSi falla, tienes dependencias implícitas o globales que no están declaradas.
- 2Desmarca todas las variables de tu shellAbre una terminal limpia y ejecuta solo lo que ejecuta tu CI. Lo que falte es lo que falta en el servidor.
- 3Fija la versión exacta de runtimeUsa .nvmrc, engines en package.json o un Dockerfile que especifique la imagen base.
Recursos para profundizar
C4C7OPS
Deploys predecibles, sin el 'en mi máquina funciona'
C4C7OPS valida la paridad de entornos, detecta variables ausentes y ejecuta builds reproducibles antes de llegar a producción.