¡Hola developer 👋🏻! En algún momento todos nos encontramos con la misma necesidad: “Necesito servir iconos, logos o pequeños assets estáticos… pero no quiero montar un servidor, ni pagar un CDN, ni complicarme la vida.”
La buena noticia es que puedes hacerlo gratis, de forma rápida, geodistribuida y apoyándote únicamente en GitHub y jsDelivr.
📝 Nota: jsDelivr es una CDN open source y gratuita que permite servir rápidamente bibliotecas de JavaScript populares y otros recursos web (como CSS, imágenes) desde una red global de servidores, acelerando la carga de sitios web al almacenar archivos estáticos en caché cerca de los usuarios
En este artículo te enseño cómo desde GitHub puedes servir de forma sencilla estos estáticos a través de jsDelivr, y cómo recuperar los assets de forma estática y de forma dinámica ¡Empecemos!
🧠 La idea clave
El concepto es muy simple:
- Guardas tus assets estáticos en un repositorio público de GitHub
- jsDelivr actúa como CDN gratuito
- Sirves esos archivos directamente desde una URL cacheada y distribuida globalmente
👉 Sin servidores, sin cuentas cloud, sin coste
📦 El repositorio de ejemplo
Para mostrartelo de forma sencilla, lo mejor es verlo en acción 🎬 Así que, para ello, he creado un repositorio de ejemplo con la siguiente estructura:
my-assets/
├── icons/
│ ├── home.svg
│ ├── search.svg
│ ├── user.svg
│ ├── settings.svg
│ ├── heart.svg
│ ├── star.svg
│ ├── mail.svg
│ └── bell.svg
│
├── logos/
│ └── logo.svg
│
├── data/
│ ├── manifest.json
│ └── data-uri.json
│
├── .github/
│ └── workflows/
│ └── update-data.yml
│
└── README.md
Con ella tengo contemplada, por ahora, el consumo estático de los iconos y logos y el dinámico usando un manifiesto y las data-uris ya generadas de los diferentes elementos de los cuales este repositorio es fuente, y que gracias a un flujo de GitHub Actions que actualiza este último directorio cada vez que el mismo se actualiza o se añaden, editan y/o eliminan estáticos, no necesito mantenerlo a mano ¿A que mola?
🚀 Cómo funciona jsDelivr con GitHub
jsDelivr permite acceder a cualquier archivo público de GitHub usando esta URL base:
https://cdn.jsdelivr.net/gh/[usuario]/[repositorio]@[version]/[ruta]Ejemplo real:
https://cdn.jsdelivr.net/gh/0gis0/my-assets/icons/heart.svgSi accedes a la misma verás un corazón como el siguiente:
Sin embargo, si utilizas directamente esta dirección, sin indicar ningún tag, estarás apuntando a la última versión que esté disponible en el branch por defecto, en este caso main.
Para este artículo he creado dos versiones diferentes de los iconos: La v1.0.0 y la v2.0.0 para que puedas ver que es posible utilizar diferentes versiones de tus assets si fuera necesario. Por ejemplo, ahora vamos a tomar el icono home para nuestra prueba. Si usamos la siguiente URL, la cual está apuntando a la versión v1.0.0:
https://cdn.jsdelivr.net/gh/0gis0/my-assets@v1.0.0/icons/home.svgObtendrás algo como lo siguiente:
Si quieres acceder a la versión v.2.0.0, solamente tienes que utilizar este otro tag en su lugar:
https://cdn.jsdelivr.net/gh/0gis0/my-assets@v2.0.0/icons/home.svgY obtendrás esta otra versión de home:
✅ Uso recomendado: versionado explícito
✔️ Evitas cambios inesperados
✔️ Mejor control de caché
✔️ Reproducibilidad total
🔄 Consumo dinámico con manifest.json
Como ya te comenté, como parte de la estructura de este repositorio también he incluido el archivo data/manifest.json. con él lo que consigo es centrarlizar todas las rutas que tenemos disponibles como parte de este repositorio, lo cual me permite poder cambiar los assets de forma dinámica sin tocar el código, lo cual es ideal para microfrontends o design systems.
const response = await fetch(
'https://cdn.jsdelivr.net/gh/tu-usuario/my-assets@main/data/manifest.json'
);
const manifest = await response.json();
const iconPath = manifest.assets.icons.home.path;
const iconUrl = `${manifest.baseUrl}/${iconPath}`;
document.querySelector('img').src = iconUrl;
🚀 Modo performance extremo: Data URIs
Cuando quieres cero peticiones HTTP adicionales, entra en juego data-uri.json. Sobre todo cuando estamos pensando en iconos críticos, apps muy sensibles al performance o conseguir un primer render ultra rápido.
const response = await fetch(
'https://cdn.jsdelivr.net/gh/tu-usuario/my-assets@main/data/data-uri.json'
);
const dataUris = await response.json();
document.querySelector('img').src = dataUris.assets.icons.home;También en CSS dinámico:
const style = document.createElement('style');
style.textContent = `
.home-icon {
background-image: url('${dataUris.assets.icons.home}');
}
`;
document.head.appendChild(style);
🤖 Automatización: generación automática de data con GitHub Actions
Para que este enfoque sea realmente cómodo en el día a día, en el repositorio he añadido también un flujo de GitHub Actions que se encarga de mantener actualizada la carpeta data.
¿Qué hace exactamente?
Cada vez que ocurre cualquiera de estos casos:
- Se añade un nuevo icono SVG
- Se añade un nuevo logo
- Se modifica un asset existente
La acción:
- Detecta los cambios en las carpetas de assets (
icons/,logos/) - Regenera automáticamente:
manifest.jsondata-uri.json
- Hace commit de los cambios en la carpeta
data/
👉 Resultado: no tengo que tocar a mano ningún JSON
👉 Los consumidores del CDN siempre tienen los assets sincronizados
Si quieres saber más sobre Github Actions te recomiendo que eches un vistazo a mi curso en mi canal de YouTube:
📝 Buenas prácticas
Espero que te haya gustado el artículo y que te sirva para poder tener una opción más si en algún momento te encuentras con esta necesidad. Como buenas prácticas te dejo las siguientes:
- ✅ Usa tags de versión en producción
- ✅ Mantén SVGs optimizados
- ✅ Usa
manifest.jsonsi hay consumo dinámico - ⚠️ No es para assets privados o sensibles
- ⚠️ No es para contenido que cambie constantemente
Este patrón es uno de esos trucos simples pero muy potentes que merece la pena tener en tu caja de herramientas como developer, por si en algún momento en un proyecto personal necesitas hospedar y mejorar el rendimiento de tu página.
¡Nos vemos 👋🏻!
