Init Initialize App
Initialize your Blue Bird application.
npx blue-bird
A powerful structure based on Express and React, designed to build fast applications with everything you need pre-configured.
npm install @seip/blue-bird
Tired of configuring CORS, Cookies, and Routing every time you start a project? Blue Bird provides a solid, pre-configured foundation so you can go straight to the business logic, without losing the pure extensibility of Express.
Express, React (with Vite), Tailwind CSS, JWT Auth, and more. Everything ready to use.
Hybrid SSR for SEO, in-memory caching, and optimized bundle for instant loading.
Response in microseconds. Rendered templates are stored in the server's RAM.
Automatic XSS protection in every validation and professional error handling that never exposes your code.
Native compression enabled. Your assets and JSON travel at the maximum speed possible across the network.
Initialize your Blue Bird application.
npx blue-bird
Set up React for your Blue Bird application.
npm run react
Edit package.json for "module" support and "type": "module"
{
"type": "module",....
}
Start the backend server:
npm run dev
Start the frontend server (Vite):
npm run vite:dev
Configure environment variables for your application.
# Public URL (SEO, Sitemap, Swagger)
APP_URL="https://blue-bird.com"
# Server Configuration
HOST="localhost"
PORT=3000
# Global Metadata (Fallback)
TITLE_META="Blue Bird"
DESCRIPTION_META="My amazing project"
| Variable | Description |
|---|---|
| APP_URL | The public URL of your site. Crucial for generating correct sitemaps and absolute SEO tags. |
| HOST | Network interface where the server listens (use 'localhost' for Nginx or '0.0.0.0' for direct access). |
| PORT | Internal application port. |
Central configuration for your Express server.
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();
| Option | Type | 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 |
Manage your routes in a modular and clean way.
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) => {
// SPA Rendering with React
return Template.renderReact(res, "App", { title: "My Project" });
})
export default routerUsers;
Render React components with automated SEO and multi-language support.
The router.seo() method allows registering
multiple
routes with their metadata and props in a single call.
import Router from "@seip/blue-bird/core/router.js";
import seoData from "./seo.js"; // External SEO data file
const frontendRouter = new Router();
// Option A: Simple meta (no i18n)
frontendRouter.seo([
{ path: "/", component: "Home", meta: { titleMeta: "Home", descriptionMeta: "Welcome" }, props: { id: 1 } }
]);
// Option B: Multilingual with external seoData file (recommended)
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 });
// Generates: /, /en, /es, /about, /en/about, /es/about
// Option C: Multilingual inline
frontendRouter.seo([
{
path: "/",
component: "Home",
meta: {
en: { titleMeta: "Home", descriptionMeta: "Welcome" },
es: { titleMeta: "Inicio", descriptionMeta: "Bienvenido" }
}
}
], { languages: ["en", "es"], defaultLanguage: "en" });
Similar to the seo.php pattern, centralizes
multilingual meta tags:
// 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" }
}
};
This method is ideal for SEO because bots and AI detect the initial server-side rendering with the correct meta tags (title, description, keywords) before React's JavaScript takes control.
The framework now supports social media tags and automatic generation of essential files for search engines.
// SPA Navigation: when ?source=frontend is detected, renderReact
// returns JSON {meta, props, component, lang} instead of HTML.
fetch('/about?source=frontend')
.then(r => r.json())
.then(data => {
// data = { meta: {titleMeta, descriptionMeta, ...}, props: {...}, component: "About", lang: "en" }
});
By using router.seo(), /sitemap.xml and
/robots.txt routes are automatically registered, linked to the host
configured in core/config.js.
Remember to delete the files, if you have sitemap.xml or robots.txt in
frontend/public, for this change to take effect
Automatic injection of og:title, og:image, and
twitter:card tags so your links look perfect when shared on social
media.
Ideal for Landing Pages, Terms & Conditions, or Privacy Policies that require instant loading without the weight of React.
router.get("/", (req, res) => {
// Loads frontend/landing.html, applies SEO from .env and stores it in RAM cache
return Template.renderHtml(res, "landing", {
withAssets: false, // Zero JavaScript for maximum speed
metaTags: { titleMeta: "Exclusive Offer" }
});
});
You can register the same route in Express and React Router Dom to create a hybrid experience:
If you need more control, you can use
Template.renderReact directly. It automatically handles the
<html lang="..."> attribute if langMeta is provided.
import Template from "@seip/blue-bird/core/template.js";
router.get("/custom", (req, res) => {
return Template.renderReact(res, "Custom", { some: "prop" }, {
metaTags: {
titleMeta: "Custom Page",
descriptionMeta: "Custom description",
langMeta: "en" // Automatically sets
},
skeleton: true // Automatically enables skeleton loading
});
});
Validate input data with automatic XSS prevention.
Support es,en,pt,br,frimport Validator from "@seip/blue-bird/core/validate.js";
const schema = {
// XSS sanitization is applied by default to all string fields.
email: { required: true, email: true },
password: { required: true, min: 6 },
// You can explicitly disable it to allow HTML/React content
html_content: { required: true, xss: false }
};
const validate = new Validator(schema, 'en');
// The second parameter allows returning localized errors based on client language.
router.post("/register", validate.middleware(), (req, res) => {
res.json({ message: "OK" });
});
The validator automatically detects the language for error
messages in this order: Body, Query String, Cookies, or the Accept-Language
header.
Option A: Using Headers (Recommended)
fetch('/api/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept-Language': 'en' // Validator will return errors in English
},
body: JSON.stringify(data)
});
Option B: URL Query Params
// Useful for quick tests or direct links
fetch('/api/register?lang=en', {
method: 'POST',
body: JSON.stringify(data)
});
Option C: Inside JSON Body
fetch('/api/register', {
method: 'POST',
body: JSON.stringify({
...data,
lang: 'pt' // Highest priority over others
})
});
Blue Bird integrates native support for multiple languages in the frontend via a Context
Provider, using the blue_bird_lang key in localStorage to
persist user preference.
Note: By default, Blue Bird already includes
LanguageProvider in
App.jsx to manage multi-language applications natively. If you wish to
remove it, simply edit App.jsx and remove the provider wrapping.
import { LanguageProvider } from './blue-bird/contexts/LanguageContext.jsx';
export default function App() {
return (
<LanguageProvider>
<Router>
{/* Your routes */}
</Router>
</LanguageProvider>
);
}
Then, inside any component or page, you can use the
useLanguage() hook:
import { useLanguage } from '../../blue-bird/contexts/LanguageContext.jsx';
export default function Login() {
const { t, lang, setLang } = useLanguage();
return (
<div>
{/* Translations are located in frontend/resources/js/blue-bird/locales/[lang].json */}
<p className="error">{t('general_error')}</p>
</div>
);
}
To speed up development, we include elegant React components ready to use. They are
styled with Tailwind CSS (which is now natively integrated via Vite in
vite.config.js, ensuring optimal performance). Highlights:
Helmet is not applied globally by default. Apply it per-router where
needed using App.helmet().
import App from "@seip/blue-bird/core/app.js";
import Router from "@seip/blue-bird/core/router.js";
// Apply helmet to a specific router
const webRouter = new Router("/web");
webRouter.use(App.helmet()); // Helmet with defaults
webRouter.use(App.helmet({ contentSecurityPolicy: false })); // Custom options
// Or enable globally in App constructor (not recommended)
new App({ helmet: true });
// Helmet with custom CSP
new App({
helmet: {
contentSecurityPolicy: {
directives: {
"script-src": ["'self'", "'unsafe-inline'"],
"style-src": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
}
}
}
});
Applying Helmet globally can block inline scripts, CDNs or styles on routes that don't need it (APIs, static landing pages). Applying it per-router gives you granular control over which routes have CSP protection.
The framework includes an SPAProvider that bridges React Router navigation
with backend SEO data.
On every <Link> navigation, it fetches meta/props from the backend
and updates document.title + meta tags automatically.
import { SPAProvider } from './blue-bird/contexts/SPAContext.jsx';
// Wrap routes with SPAProvider
<SPAProvider languages={["en", "es"]} defaultLanguage="en">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
{/* Language-prefixed routes are auto-generated */}
<Route path="/en" element={<Home />} />
<Route path="/es" element={<Home />} />
<Route path="/en/about" element={<About />} />
<Route path="/es/about" element={<About />} />
</Routes>
</SPAProvider>
import { useSPA } from './blue-bird/contexts/SPAContext.jsx';
Navigation Components (Recommended)
The framework provides components that encapsulate localization logic for a cleaner syntax.
1. <Link /> Component
Replaces react-router-dom's Link to automatically persist the current language.
import Link from "../blue-bird/components/Link";
// Automatically prepends /es/ or /en/ based on the current session
<Link to="/about">About Us</Link>
2. <LanguageButton /> Component
Encapsulates the navigateToLang logic.
import LanguageButton from "../blue-bird/components/LanguageButton";
<LanguageButton lang="es" variant="outline">Spanish</LanguageButton>
<LanguageButton lang="en" variant="outline">English</LanguageButton>
Monolingual Support
If your application only uses one language, simply leave the LANGUAGES
array empty in App.jsx. The framework will automatically disable all prefix
logic.
// App.jsx
const LANGUAGES = []; // Monolingual application
const DEFAULT_LANGUAGE = "en";
🔄 How does it work?
- Initial load: Express serves full HTML with correct SEO meta
tags.
- Client navigation: When clicking a
<Link>,
SPAProvider does fetch(path?source=frontend).
- Backend responds JSON:
{meta, props, component, lang} instead of HTML.
- React updates: document.title, meta tags and localStorage
language.
Each Router supports the use() method to apply middlewares to
all routes within that router.
This is ideal for protecting groups of routes without repeating the middleware in each
one.
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 only for this router
// All routes in this router are protected by Helmet
routerFrontend.get("/", (req, res) => { ... });
routerFrontend.get("/about", (req, res) => { ... });
Perfect for creating admin, dashboard, or authenticated routers. The middleware is applied once and protects all routes in the 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";
// Option 1: Using pre-configured Middleware
const routerAdmin = new Router("/admin");
routerAdmin.use(Middleware.auth); // All routes require JWT
routerAdmin.get("/dashboard", (req, res) => {
res.json({ user: req.user }); // req.user available in all routes
});
routerAdmin.get("/settings", (req, res) => {
res.json({ settings: {} });
});
// Option 2: Using Auth.protect() with redirect
const routerDashboard = new Router("/dashboard");
routerDashboard.use(Auth.protect({ redirect: "/login" }));
routerDashboard.get("/", (req, res) => {
return Template.renderReact(res, "Dashboard");
});
const routerApi = new Router("/api");
// Custom logging middleware
routerApi.use((req, res, next) => {
console.log(`[API] ${req.method} ${req.url}`);
next();
});
// Multiple middlewares
routerApi.use(Middleware.auth);
routerApi.use(App.helmet());
routerApi.get("/users", (req, res) => { ... });
Use router.use() to group routes with the same protection level.
Create one router per permission group: routerPublic,
routerAuth, routerAdmin.
Register them all in
App({ routes: [routerPublic, routerAuth, routerAdmin, routerFrontend] }).
Protect API and React routes with JWT authentication. Tokens are read from Cookies or
the Authorization header.
import Auth from "@seip/blue-bird/core/auth.js";
// Protect API route (returns 401 on failure):
router.get("/profile", Auth.protect(), (req, res) => {
res.json({ user: req.user });
});
// Protect React route (redirects to login):
router.get("/dashboard", Auth.protect({ redirect: "/login" }), (req, res) => {
return Template.renderReact(res, "Dashboard");
});
// Generate token:
const token = Auth.generateToken({ id: user.id, email: user.email });
// Verify token:
const decoded = Auth.verifyToken(token);
import Middleware from "@seip/blue-bird/core/middleware.js";
// Pre-configured auth middleware
router.get("/api/profile", Middleware.auth, controller.profile);
// Web auth middleware (redirects to / on failure)
router.get("/dashboard", Middleware.webAuth, (req, res) => {
return Template.renderReact(res, "Dashboard");
});
Simple in-memory cache middleware for JSON responses. Improves performance by avoiding repeated controller execution during a defined period.
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 seconds
controller.stats
);
//Testing
routerStats("/stats_",
Cache.middleware(120),
async (req, res) => {
await new Promise(resolve => setTimeout(resolve, 2000));
res.json({
message: 'Login successful',
note: 'This response took 2 seconds to arrive.'
});
}
);
| Parameter | Type | Default | Description |
|---|---|---|---|
| seconds | Number | 60 | Time in seconds that the response remains in cache. |
req.originalUrl as the cache key.res.json() to store the response.Automatic documentation integration using Swagger (OpenAPI 3). Allows viewing and testing endpoints directly from the browser.
First install Swagger with npm or blue-bird CLI:
npm run swagger-install
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"
}
})
/**
* @swagger
* /users:
* get:
* summary: Get all users
* tags: [Users]
* responses:
* 200:
* description: List of users
*/
router.get("/users", controller.getUsers);
/**
* @swagger
* components:
* schemas:
* User:
* type: object
* properties:
* name:
* type: string
* email:
* type: string
*/
/docs.components.securitySchemes.
@swagger comments must be correctly indented./docs.The Debug module allows monitoring your application's performance in real-time. It records metrics such as response time, RAM usage, CPU consumption, and per-route statistics. When Debug=true in .env, the route is enabled.
Then access the visual panel at:
http://localhost:3000/debug
fetch/debug?fetch=true/debug route itselfGET /debug?fetch=true
Returns metrics in JSON format:
{
"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
}
}
}
Blue Bird is designed for production. With features like caching, gzip compression, and robust error handling, you can be sure your application will perform correctly.
For production, it is recommended to use a proxy server like Nginx to handle SSL, gzip compression, and load balancing.
First edit .env, setting DEBUG=false
DEBUG=false
Then run the command to generate the React build with Vite:
npm run vite:build
To run in production "npm run start" is used, so with PM2 we will do:
pm2 start npm --name "blue-bird" -- run start
This will start the application in production and keep it
alive.
pm2 save
This will save the PM2 configuration so it starts
automatically when the server reboots.