¡Hola developer 👋🏻! Cuando un proyecto tiene más de un componente ejecutable, por ejemplo un backend en Spring Boot y un frontend con Vite, o simplemente quieres poder ejecutar tu aplicación de diferentes formas, el archivo launch.json de VS Code pasa de ser una comodidad a convertirse en una herramienta de trabajo muy útil. Bien configurado, permite arrancar servicios, abrir el navegador y encadenar procesos sin depender de pasos manuales. Esta semana he publicado un vídeo en mi canal de YouTube donde puedes ver diferentes configuraciones para que puedas ver lo útil que es👇🏻
Y en este artículo quiero dejarte las configuraciones que mostré durante el mismo con su correspondiente explicación para que te sea lo más sencillo posible copiarlas y adaptarlas a tus aplicaciones 😃
Qué es launch.json
launch.json es el archivo donde VS Code guarda las configuraciones de ejecución y depuración de un proyecto. Se encuentra normalmente dentro de la carpeta .vscode en la raíz del repositorio.
Cada entrada dentro de configurations es una receta. Esa receta le dice a VS Code qué debe ejecutar, con qué depurador, desde qué carpeta y con qué comportamiento adicional.
En este ejemplo real, el archivo define cuatro configuraciones principales y un compound:
{
"configurations": [
{
"type": "java",
"name": "☕ Backend (Spring Boot)",
"request": "launch"
},
{
"type": "node",
"name": "🌐 Frontend (Vite Dev Server)",
"request": "launch"
},
{
"type": "msedge",
"name": "🔍 Edge: Debug Frontend",
"request": "launch"
},
{
"type": "editor-browser",
"name": "🌐 Launch Integrated Browser",
"request": "launch"
}
],
"compounds": [
{
"name": "🚀 Full Stack (Backend + Frontend)"
}
]
}Eso ya deja ver algo importante: launch.json no se limita a una sola forma de arrancar cosas. Puede lanzar procesos Java, ejecutar comandos de Node, abrir Edge para depuración o incluso abrir el navegador integrado de VS Code.
La configuración del backend
La primera pieza del ejemplo es el backend en Spring Boot:
{
"type": "java",
"name": "☕ Backend (Spring Boot)",
"request": "launch",
"mainClass": "com.ideaforge.quickstart.Application",
"cwd": "${workspaceFolder}/backend",
"env": {
"SPRING_PROFILES_ACTIVE": "default"
},
"console": "integratedTerminal"
}Aquí hay varios campos que merece la pena entender:
typeindica que se usará el depurador de Java.mainClassseñala la clase principal de Spring Boot que se debe lanzar.cwdfija la carpeta de trabajo enbackend.envpermite definir variables de entorno, en este caso el perfil activo de Spring.consolemanda la salida al terminal integrado.
Esta configuración sí representa una depuración clásica del backend: VS Code lanza la aplicación Java y puede engancharse al proceso para depurarla.
La configuración del frontend con Vite
La segunda pieza arranca el frontend:
{
"type": "node",
"name": "🌐 Frontend (Vite Dev Server)",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run",
"dev"
],
"cwd": "${workspaceFolder}/frontend",
"console": "integratedTerminal",
"skipFiles": [
"<node_modules>/**"
]
}Aquí el patrón es distinto al de Java. No se está arrancando una clase principal, sino ejecutando npm run dev desde la carpeta frontend. Eso pone en marcha el servidor de desarrollo de Vite.
Este detalle importa porque muchas veces se mezclan dos cosas distintas:
- arrancar el servidor del frontend
- abrir un navegador o una sesión de depuración sobre la aplicación web
En este launch.json esas responsabilidades están separadas, y eso está bien diseñado.
Cómo entra en juego serverReadyAction
La parte más interesante del ejemplo está dentro de la configuración del frontend, donde aparece serverReadyAction:
{
"type": "node",
"name": "🌐 Frontend (Vite Dev Server)",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"cwd": "${workspaceFolder}/frontend",
"serverReadyAction": {
"pattern": "Local:.+(https?://\\S+)",
"uriFormat": "%s",
"action": "startDebugging",
"name": "🌐 Launch Integrated Browser"
}
}Esto significa que VS Code vigila la salida del proceso de Vite y espera a detectar una línea como la que imprime normalmente el servidor:
Local: http://localhost:5176/En cuanto encuentra una URL que encaja con el patrón, dispara otra configuración con action: "startDebugging". En este caso, la configuración que se lanza es 🌐 Launch Integrated Browser.
Aquí sí hay una secuencia real: primero Vite, después el navegador.
La configuración del navegador integrado
La configuración que se dispara cuando Vite está listo es esta:
{
"name": "🌐 Launch Integrated Browser",
"request": "launch",
"type": "editor-browser",
"url": "http://localhost:5176",
"webRoot": "${workspaceFolder}"
}Su función es sencilla: abrir la aplicación dentro del navegador integrado de VS Code, usando la URL local del frontend.
Además del navegador integrado, el archivo también incluye una configuración adicional para Edge:
{
"type": "msedge",
"name": "🔍 Edge: Debug Frontend",
"request": "launch",
"url": "http://localhost:5176",
"webRoot": "${workspaceFolder}/frontend/src"
}Esa configuración está oculta en la presentación habitual y sirve como alternativa cuando interesa depurar en Edge con soporte de source maps, pero no es la que forma parte del flujo automático principal.
Compounds
Si lo que te interesa es ejecutar más de una configuración a la vez, que suele ser lo habitual cuando tienes un backend y un frontend, también te interesará configurar lo que se llaman compounds:
{
"name": "🚀 Full Stack (Backend + Frontend)",
"configurations": [
"☕ Backend (Spring Boot)",
"🌐 Frontend (Vite Dev Server)"
],
"stopAll": true
}Esto permite lanzar backend y frontend desde una única entrada. Es cómodo, pero conviene entenderlo bien: el compound no establece dependencia entre ambos procesos. Los dos arranques se lanzan en paralelo.
Eso quiere decir que, en este ejemplo, la secuencia controlada existe entre el frontend y el navegador, pero no entre el backend y el frontend.
Dicho de otra forma:
- el
compoundarranca backend y frontend al mismo tiempo - Vite termina de levantar su servidor
serverReadyActiondetecta la URL local- VS Code lanza el navegador integrado
Este matiz es importante porque a veces se dice que todo está encadenado cuando en realidad solo una parte del flujo lo está.
Cuándo usar cada pieza
Una forma práctica de pensarlo es esta:
- Usa una configuración normal cuando quieres arrancar una sola pieza, como el backend o el frontend.
- Usa un
compoundcuando quieres lanzar varias piezas desde una única orden, aunque eso ocurra en paralelo. - Usa
serverReadyActioncuando necesitas reaccionar a una señal real de disponibilidad, como la URL que imprime Vite al arrancar. - Usa una configuración de navegador separada cuando quieres distinguir claramente entre arrancar un servidor y abrir la interfaz.
Ese reparto de responsabilidades hace que el archivo sea más fácil de mantener y también más fácil de entender por parte de cualquier persona que se incorpore al proyecto.
Si quisieras secuencia completa backend → frontend → navegador
Este ejemplo no hace eso todavía. El backend y el frontend arrancan en paralelo porque así está definido el compound. Si el objetivo fuera esperar a que Spring Boot estuviera listo antes de lanzar Vite, haría falta introducir un encadenado adicional desde la configuración Java o reestructurar el flujo con tareas y dependencias.
Precisamente por eso este archivo es un buen ejemplo didáctico: muestra muy bien la diferencia entre agrupar procesos y secuenciarlos de verdad.
Conclusión
launch.json es mucho más que un archivo para pulsar F5. Bien usado, te permite describir el flujo de arranque real de tu aplicación y reducir bastante la fricción diaria.
La idea más importante es esta: los compounds agrupan, pero no ordenan. El orden real aparece cuando introduces una señal verificable del proceso, como hace aquí serverReadyAction al detectar la URL de Vite y lanzar después el navegador integrado.
Cuando entiendes esa diferencia, launch.json deja de ser un archivo misterioso y se convierte en una herramienta muy potente para automatizar el desarrollo local 🚀
¡Nos vemos 👋🏻!
