El Framework JS para
Desarrolladores Modernos.

Una estructura potente basada en Express y React, diseñada para construir aplicaciones rápidas y todo lo que necesitas pre-configurado.

Ver Documentación
npm install @seip/blue-bird

La Filosofía Blue Bird

¿Cansado de configurar CORS, Cookies, etc y el Routing cada vez que empiezas un proyecto? Blue Bird proporciona una base sólida y pre-configurada para que vayas directo a la lógica de negocio, sin perder la extensibilidad pura de Express.

⚡ Todo en Uno

Express, React (con Vite), Tailwind CSS, JWT Auth y más. Todo listo para usar.

🚀 Rendimiento Extremo

SSR Híbrido para SEO, caché en memoria y bundle optimizado para una carga instantánea.

RAM Caching

Respuesta en microsegundos. Las plantillas renderizadas se guardan en la memoria RAM del servidor.

🛡️

Safe by Design

Protección XSS automática en cada validación y manejo de errores profesional que nunca expone tu código.

📦

Gzip Boost

Compresión nativa activada. Tus assets y JSON viajan a la máxima velocidad posible por la red.

Init Inicializar App

Inicializa tu aplicación Blue Bird.

npx blue-bird

React Configuración React

Configura React para tu aplicación Blue Bird.

npm run react

Dev Configuración Dev (Express + Vite)

Editar package.json para soporte "module" y "type": "module"

{
  "type": "module",....
}

Inicia el servidor backend:

npm run dev

Inicia el servidor frontend (Vite):

npm run vite:dev

E Configuración (.env)

Configura las variables de entorno para tu aplicación.

# URL Pública (SEO, Sitemap, Swagger)
APP_URL="https://blue-bird.com"

# Configuración del Servidor
HOST="localhost"
PORT=3000

# Metadatos Globales (Fallback)
TITLE_META="Blue Bird"
DESCRIPTION_META="Mi increíble proyecto"
Variable Descripción
APP_URL La URL pública de tu sitio. Es crucial para generar sitemaps correctos y etiquetas SEO absolutas.
HOST Interfaz donde escucha el servidor (usar 'localhost' para Nginx o '0.0.0.0' para acceso directo).
PORT Puerto interno de la aplicación.

App Clase App principal

Configuración central de tu servidor Express.

import App from "@seip/blue-bird/core/app.js";
import routerUsers from "./routes/users.js";

const app = new App({
    port: 3000,
    routes: [routerUsers],
    cors:{},
    rateLimit:{
          windowMs: 10 * 60 * 1000, 
           max: 300
        }
});

app.use(myCustomMiddleware);

app.run();
Opción Tipo Default
routes Array []
middlewares Array []
port Number 3000
host String "http://localhost"
cors Object {}
static Object { path: null, options: {} }
rateLimit Boolean | Object false
logger Boolean false
notFound Boolean true
json Boolean true
urlencoded Boolean true
cookieParser Boolean true
swagger Boolean | Object false
  • Registra método HTTP, IP y URL.
  • Oculta automáticamente parámetros sensibles (password, token).
  • Guarda logs en archivo.
  • En modo Debug muestra logs coloreados en consola.

R Router

Gestiona tus rutas de forma modular y limpia.

import Router from "@seip/blue-bird/core/router.js";
import Template from "@seip/blue-bird/core/template.js";

const routerUsers = new Router("/")

routerUsers.get("/users", (req, res) => {
    const users = [
        {
            name: "John Doe",
            email: "john.doe@example.com",
        },
        {
            name: "Jane Doe2",
            email: "jane.doe2@example.com",
        },
    ]
    res.json(users)
})

routerUsers.get("*", (req, res) => {
    // Renderizado SPA con React
    return Template.renderReact(res, "App", { title: "Mi Proyecto" });
})

export default routerUsers;

T Template & SEO

Renderiza componentes React con SEO automatizado y soporte multi-idioma.

SEO Routing Práctico

El método router.seo() permite registrar múltiples rutas con sus metadatos y props en una sola llamada.

import Router from "@seip/blue-bird/core/router.js";
import seoData from "./seo.js"; // Archivo externo de datos SEO

const frontendRouter = new Router();

// Opción A: Meta simple (sin i18n)
frontendRouter.seo([
    { path: "/", component: "Home", meta: { titleMeta: "Home", descriptionMeta: "Bienvenido" }, props: { id: 1 } }
]);

// Opción B: Multilenguaje con archivo externo seoData (recomendado)
frontendRouter.seo([
    { path: "/", component: "Home", seoKey: "home", props: { id: 1 } },
    { path: "/about", component: "About", seoKey: "about", props: { id: 2 } }
], { languages: ["en", "es"], defaultLanguage: "en", seoData });
// Genera: /, /en, /es, /about, /en/about, /es/about

// Opción C: Multilenguaje inline
frontendRouter.seo([
    {
        path: "/",
        component: "Home",
        meta: {
            en: { titleMeta: "Home", descriptionMeta: "Welcome" },
            es: { titleMeta: "Inicio", descriptionMeta: "Bienvenido" }
        }
    }
], { languages: ["en", "es"], defaultLanguage: "en" });

Archivo SEO Externo (seo.js)

Similar al patrón seo.php, centraliza los meta tags multilenguaje:

// backend/routes/seo.js
export default {
  home: {
    en: { titleMeta: "Home - Blue Bird", descriptionMeta: "Welcome", keywordsMeta: "home" },
    es: { titleMeta: "Inicio - Blue Bird", descriptionMeta: "Bienvenido", keywordsMeta: "inicio" }
  },
  about: {
    en: { titleMeta: "About", descriptionMeta: "About us" },
    es: { titleMeta: "Acerca", descriptionMeta: "Acerca de nosotros" }
  }
};
💡 Ventaja SEO/AI

Este método es ideal para el SEO porque los bots e IAs detectan el renderizado inicial desde el servidor con los meta tags correctos (title, description, keywords) antes de que el JavaScript de React tome el control.

SEO Avanzado (Social & Automatización)

El framework ahora soporta etiquetas para redes sociales y generación automática de archivos esenciales para buscadores.

// Navegación SPA: cuando ?source=frontend se detecta, renderReact
// devuelve JSON {meta, props, component, lang} en vez de HTML.
fetch('/about?source=frontend')
  .then(r => r.json())
  .then(data => {
    // data = { meta: {titleMeta, descriptionMeta, ...}, props: {...}, component: "About", lang: "en" }
  });
🌐 Sitemap & Robots

Al usar router.seo(), se registran automáticamente las rutas /sitemap.xml y /robots.txt, vinculadas al host configurado en core/config.js. Recuerda eliminar los archivos,si tienes sitemap.xml o robots.txt en frontend/public , para que este cambio se aplique

📱 Social Ready

Inyección automática de tags og:title, og:image y twitter:card para que tus enlaces luzcan perfectos al compartirse en redes sociales.

Plantillas HTML & Estrategia Híbrida

Ideal para Landing Pages, Términos y Condiciones o Políticas de Privacidad que requieren una carga instantánea sin el peso de React.

router.get("/", (req, res) => {
    // Carga frontend/landing.html, aplica SEO de .env y lo guarda en caché RAM
    return Template.renderHtml(res, "landing", { 
        withAssets: false, // Zero JavaScript para máxima velocidad
        metaTags: { titleMeta: "Oferta Exclusiva" } 
    });
});
⚡ Estrategia: Colisión Controlada

Puedes registrar la misma ruta en Express y en React Router Dom para crear una experiencia híbrida:

  1. Carga Inicial: El servidor sirve un HTML estático (Landing) al instante.
  2. Hidratación: React se monta en segundo plano.
  3. Navegación: Al navegar dentro de la SPA, React Router toma el control de la ruta "/" permitiendo mostrar otro componente (ej: Login) sin recargar la página.

Renderizado Manual

Si necesitas más control, puedes usar Template.renderReact directamente. Maneja automáticamente el atributo <html lang="..."> si se provee langMeta.

import Template from "@seip/blue-bird/core/template.js";

router.get("/custom", (req, res) => {
    return Template.renderReact(res, "Custom", { some: "prop" }, {
        metaTags: {
            titleMeta: "Página Custom",
            descriptionMeta: "Descripción custom",
            langMeta: "es" // Setea automáticamente 
        },
        skeleton: true // Habilita el skeleton loading automáticamente
    });
});

V Validator

Valida datos de entrada con prevención automática de XSS.

Soporta es,en,pt,br,fr (Español,Ingles,Portugues,Brasil-Portugues,Frances)
import Validator from "@seip/blue-bird/core/validate.js";

const schema = {
    // La sanitización XSS se aplica por defecto a todos los campos string.
    email: { required: true, email: true },
    password: { required: true, min: 6 },
    // Puedes desactivarla explícitamente para permitir contenido HTML/React
    html_content: { required: true, xss: false }
};

const validate = new Validator(schema, 'es');
// El segundo parámetro permite devolver errores localizados según el idioma del cliente.

router.post("/register", validate.middleware(), (req, res) => {
    res.json({ message: "OK" });
});

Localización de Errores (API)

El validador detecta automáticamente el idioma para los mensajes de error en este orden: Body, Query String, Cookies o el Header Accept-Language.

Opción A: Usando Headers (Recomendado)

fetch('/api/register', {
    method: 'POST',
    headers: { 
        'Content-Type': 'application/json',
        'Accept-Language': 'es' // El validador devolverá errores en español
    },
    body: JSON.stringify(data)
});

Opción B: URL Query Params

// Útil para pruebas rápidas o links directos
fetch('/api/register?lang=esp', { 
    method: 'POST',
    body: JSON.stringify(data)
});

Opción C: En el Body JSON

fetch('/api/register', {
    method: 'POST',
    body: JSON.stringify({
        ...data,
        lang: 'pt' // Prioridad máxima sobre el resto
    })
});

UI Frontend & Componentes

Soporte Multilenguaje

Lila integra soporte nativo para múltiples idiomas en el frontend mediante un Context Provider, usando la clave blue_bird_lang en el localStorage para mantener la preferencia del usuario.

Nota: Por defecto, Blue Bird ya incluye LanguageProvider en App.jsx para gestionar aplicaciones multiidioma de forma nativa. Si deseas removerlo, simplemente edita App.jsx y elimina el wrapping del provider.

import { LanguageProvider } from './blue-bird/contexts/LanguageContext.jsx';

export default function App() {
  return (
    <LanguageProvider>
      <Router>
        {/* Tus rutas */}
      </Router>
    </LanguageProvider>
  );
}

Luego, dentro de cualquier componente o página puedes utilizar el hook useLanguage():

import { useLanguage } from '../../blue-bird/contexts/LanguageContext.jsx';

export default function Login() {
  const { t, lang, setLang } = useLanguage();

  return (
    <div>
      {/* Las traducciones están en frontend/resources/js/blue-bird/locales/[lang].json */}
      <p className="error">{t('error_general')}</p>
    </div>
  );
}

Componentes Pre-construidos

Para acelerar el desarrollo, incluimos componentes React elegantes y listos para usar. Están estilizados con Tailwind CSS (el cual ahora se integra nativamente vía Vite en vite.config.js, asegurando un rendimiento óptimo). Destacan:

  • Button: Botones con diversas variantes y estados.
  • Input: Campos de texto accesibles y estandarizados.
  • Card: Contenedores limpios.
  • Snackbar / SnackbarContext: Notificaciones flotantes (toasts) para feedback rápido.
  • Typography: Estilos base unificados para tus textos.

H Helmet (Seguridad)

Helmet no se aplica globalmente por defecto. Aplícalo por router donde sea necesario usando App.helmet().

import App from "@seip/blue-bird/core/app.js";
import Router from "@seip/blue-bird/core/router.js";

// Aplicar helmet a un router específico
const webRouter = new Router("/web");
webRouter.use(App.helmet()); // Helmet con defaults
webRouter.use(App.helmet({ contentSecurityPolicy: false })); // Opciones custom

// O habilitar globalmente en el constructor de App (no recomendado)
new App({ helmet: true });

// Helmet con CSP personalizado
new App({
    helmet: {
        contentSecurityPolicy: {
            directives: {
                "script-src": ["'self'", "'unsafe-inline'"],
                "style-src": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
            }
        }
    }
});
💡 ¿Por qué opt-in?

Aplicar Helmet globalmente puede bloquear scripts inline, CDNs o estilos en rutas que no lo necesitan (APIs, landing pages estáticas). Aplicándolo por router tienes control granular sobre qué rutas tienen protección CSP.

S SPA Navigation (SPAProvider)

El framework incluye un SPAProvider que conecta la navegación de React Router con los datos SEO del backend. En cada navegación por <Link>, hace un fetch al backend y actualiza document.title + meta tags automáticamente.

Configuración en App.jsx

import { SPAProvider } from './blue-bird/contexts/SPAContext.jsx';

// Envolver las rutas con SPAProvider
<SPAProvider languages={["en", "es"]} defaultLanguage="en">
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/about" element={<About />} />
    {/* Las rutas con prefijo de idioma se generan automáticamente */}
    <Route path="/en" element={<Home />} />
    <Route path="/es" element={<Home />} />
    <Route path="/en/about" element={<About />} />
    <Route path="/es/about" element={<About />} />
  </Routes>
</SPAProvider>

Componentes de Navegación (Recomendado)

El framework provee componentes que encapsulan la lógica de localización para una sintaxis más limpia.

1. Componente <Link />

Reemplaza el Link de react-router-dom para persistir el idioma automáticamente.

import Link from "../blue-bird/components/Link";

// El componente añade el prefijo /es/ o /en/ automáticamente según la sesión
<Link to="/about">Sobre nosotros</Link>
2. Componente <LanguageButton />

Encapsula la lógica de navigateToLang.

import LanguageButton from "../blue-bird/components/LanguageButton";

<LanguageButton lang="es" variant="outline">Español</LanguageButton>
<LanguageButton lang="en" variant="outline">English</LanguageButton>

Soporte Monolingüe

Si tu aplicación solo usa un idioma, simplemente deja el array LANGUAGES vacío en App.jsx. El framework desactivará automáticamente toda la lógica de prefijos.

// App.jsx
const LANGUAGES = []; // Aplicación monolingüe
const DEFAULT_LANGUAGE = "es";
🔄 ¿Cómo funciona?
  • Carga inicial: Express sirve HTML completo con meta tags correctos del SEO.
  • Navegación cliente: Al hacer click en un <Link>, SPAProvider hace fetch(path?source=frontend).
  • Backend responde JSON: {meta, props, component, lang} en vez de HTML.
  • React actualiza: document.title, meta tags y localStorage del idioma.

M Router Middlewares

Cada Router soporta el método use() para aplicar middlewares a todas las rutas de ese router. Esto es ideal para proteger grupos de rutas sin repetir el middleware en cada una.

Helmet por Router

import Router from "@seip/blue-bird/core/router.js";
import App from "@seip/blue-bird/core/app.js";

const routerFrontend = new Router();
routerFrontend.use(App.helmet()); // Helmet solo para este router

// Todas las rutas de este router están protegidas por Helmet
routerFrontend.get("/", (req, res) => { ... });
routerFrontend.get("/about", (req, res) => { ... });

Router Protegido con Auth

Perfecto para crear routers de admin, dashboard o rutas autenticadas. El middleware se aplica una sola vez y protege todas las rutas del router.

import Router from "@seip/blue-bird/core/router.js";
import Middleware from "@seip/blue-bird/core/middleware.js";
import Auth from "@seip/blue-bird/core/auth.js";

// Opción 1: Usando Middleware pre-configurado
const routerAdmin = new Router("/admin");
routerAdmin.use(Middleware.auth); // Todas las rutas requieren JWT

routerAdmin.get("/dashboard", (req, res) => {
    res.json({ user: req.user }); // req.user disponible en todas
});
routerAdmin.get("/settings", (req, res) => {
    res.json({ settings: {} });
});

// Opción 2: Usando Auth.protect() con redirect
const routerDashboard = new Router("/dashboard");
routerDashboard.use(Auth.protect({ redirect: "/login" }));

routerDashboard.get("/", (req, res) => {
    return Template.renderReact(res, "Dashboard");
});

Middleware Personalizado

const routerApi = new Router("/api");

// Middleware personalizado de logging
routerApi.use((req, res, next) => {
    console.log(`[API] ${req.method} ${req.url}`);
    next();
});

// Múltiples middlewares
routerApi.use(Middleware.auth);
routerApi.use(App.helmet());

routerApi.get("/users", (req, res) => { ... });
💡 Patrón Recomendado

Usa router.use() para agrupar rutas con la misma protección. Crea un router por grupo de permisos: routerPublic, routerAuth, routerAdmin. Registra todos en App({ routes: [routerPublic, routerAuth, routerAdmin, routerFrontend] }).

A Auth Middleware (JWT)

Protege rutas API y React con autenticación JWT. Los tokens se leen de Cookies o del header Authorization.

import Auth from "@seip/blue-bird/core/auth.js";

// Proteger ruta API (retorna 401 si falla):
router.get("/profile", Auth.protect(), (req, res) => {
    res.json({ user: req.user });
});

// Proteger ruta React (redirige a login):
router.get("/dashboard", Auth.protect({ redirect: "/login" }), (req, res) => {
    return Template.renderReact(res, "Dashboard");
});

// Generar token:
const token = Auth.generateToken({ id: user.id, email: user.email });

// Verificar token:
const decoded = Auth.verifyToken(token);

Middleware Pre-configurado

import Middleware from "@seip/blue-bird/core/middleware.js";

// Middleware auth pre-configurado
router.get("/api/profile", Middleware.auth, controller.profile);

// Middleware web auth (redirige a / si falla)
router.get("/dashboard", Middleware.webAuth, (req, res) => {
    return Template.renderReact(res, "Dashboard");
});

C Cache Middleware

Middleware simple de cache en memoria para respuestas JSON. Permite mejorar el rendimiento evitando ejecutar el controlador repetidamente durante un período definido.

Uso Básico

import Cache from "@seip/blue-bird/core/cache.js";
import Router from "@seip/blue-bird/core/router.js"
                        
const routerStats = new Router("/")
                        
routerStats("/stats",
  Cache.middleware(120), // 120 segundos
  controller.stats
);
//Testing                    
routerStats("/stats_",
  Cache.middleware(120),
  async (req, res) => {  
    await new Promise(resolve => setTimeout(resolve, 2000));

    res.json({ 
      message: 'Login successful',
      note: 'Esta respuesta tardó 2 segundos en llegar.'
    });
  }
);                  

Parámetro

Parámetro Tipo Default Descripción
seconds Number 60 Tiempo en segundos que la respuesta permanece en cache.

Cómo Funciona

  • Usa req.originalUrl como clave de cache.
  • Intercepta res.json() para almacenar la respuesta.
  • Si la clave existe y no expiró, devuelve el JSON cacheado.
  • Si expira, ejecuta nuevamente el controlador.
  • El cache se pierde al reiniciar el servidor.

S Swagger Integration

Integración de documentación automática utilizando Swagger (OpenAPI 3). Permite visualizar y probar endpoints directamente desde el navegador.

Primero instala swagger con npm o cli blue-bird :

    
        npm run swagger-install
    

Configuración Básica


const app = new App({
    routes: [routerUsers],
    cors: {},
    middlewares: [],
    port: 3000,
    host: "http://localhost",
    swagger:{
        info: {
            title: "Blue Bird API",
            version: "1.0.0",
            description: "Blue Bird Framework API Documentation"
        },
        url : "http://localhost:8000"
    }
})
  

Uso en Rutas

/**
 * @swagger
 * /users:
 *   get:
 *     summary: Get all users
 *     tags: [Users]
 *     responses:
 *       200:
 *         description: List of users
 */
router.get("/users", controller.getUsers);

Schemas Reutilizables

/**
 * @swagger
 * components:
 *   schemas:
 *     User:
 *       type: object
 *       properties:
 *         name:
 *           type: string
 *         email:
 *           type: string
 */

Acceso

  • La documentación estará disponible en /docs.
  • Permite probar endpoints directamente desde el navegador.
  • Soporta autenticación si se define en components.securitySchemes.

⚠️ Consideraciones

  • Los comentarios @swagger deben estar correctamente indentados.
  • Las rutas deben coincidir exactamente con las definidas en Express.
  • En producción se recomienda proteger /docs.

D Debug & Métricas

El módulo Debug permite monitorear el rendimiento de tu aplicación en tiempo real. Registra métricas como tiempo de respuesta, uso de memoria RAM, consumo de CPU y estadísticas por ruta. Cuando en .env es Debug=true queda activada la ruta.

Luego accede al panel visual en:

http://localhost:3000/debug

Características

📊 Métricas Registradas
  • Tiempo de respuesta (ms)
  • Uso de memoria (RSS)
  • Consumo de CPU
  • Status HTTP
  • Historial de últimas 50 requests
⚙️ Funcionalidades
  • Auto actualización con fetch
  • Endpoint JSON: /debug?fetch=true
  • Botón de reset de métricas
  • No registra archivos estáticos
  • No registra la ruta /debug

Endpoint JSON

GET /debug?fetch=true

Devuelve las métricas en formato JSON:

{
  "requests": [
    {
      "method": "GET",
      "url": "/users",
      "status": 200,
      "responseTime": 32.14,
      "ramUsedMB": 45.21,
      "cpuUsedMS": 1.23,
      "date": "2026-02-27T12:00:00.000Z"
    }
  ],
  "routes": {
    "GET /users": {
      "count": 5,
      "totalTime": 160.5
    }
  }
}

Producción

Blue Bird está diseñado para producción. Con características como caching, compresión gzip, y manejo de errores robusto, puedes estar seguro de que tu aplicación funcionará correctamente.

Para producción, se recomienda usar un servidor proxy como Nginx para manejar el SSL, la compresión gzip, y el balanceo de carga.

Primero edita .env , poniendo DEBUG=false

DEBUG=false

Luego ejecuta el comando para generar la build de react con vite:

npm run vite:build

Para ejecutar en producción se utiliza "npm run start" , por lo que con PM2 haremos:

pm2 start npm --name "blue-bird" -- run start
Esto iniciará la aplicación en producción y la mantendrá viva .
pm2 save
Esto guardará la configuración de PM2 para que se inicie automáticamente al reiniciar el servidor.