Configuration & Env
Your entire framework behavior is controlled by a single file at the root of your project: bro.config.js.
The Template
import { defineConfig, z } from 'bro-framework';
export default defineConfig({
// Strictly validate process.env on boot!
env: z.object({
PORT: z.string().default('5000'),
MONGO_URI: z.string().url()
}),
server: {
port: 5000,
cors: true,
helmet: true // Disable or pass helmet options
},
redisUrl: process.env.REDIS_URL, // e.g., 'redis://localhost:6379'
auth: {
jwtSecret: process.env.JWT_SECRET || 'dev_secret_please_change',
expiresIn: '7d',
apiKey: process.env.API_KEY || ['dev_key_1', 'dev_key_2'] // Supports arrays for rotation
},
docs: process.env.NODE_ENV !== 'production',
rateLimit: {
windowMs: 15 * 60 * 1000,
max: 100
},
db: async () => { /* Connect to DB */ },
sockets: async (io, db) => { /* Setup events */ }
});Strict Env Validation
If you define an env Zod schema, bro.js will execute .safeParse(process.env) before anything else boots. If a required environment variable is missing, the framework immediately crashes with a red error log, preventing bad deployments!
Security: Fail-Closed Production Auth
By default, the framework starts with a placeholder jwtSecret for quick local iteration. However, bro.js employs a Fail-Closed security model. If you attempt to boot the server in NODE_ENV=production while still using a default or missing JWT secret (like dev_secret_please_change or bro_default_secret_key), the application will instantly throw a fatal exception and refuse to start, protecting you from critical production vulnerabilities.
Server Lifecycle & Graceful Shutdown
When running the application via the CLI command bro start in production, bro.js automatically intercepts operating system termination signals (SIGINT and SIGTERM) and performs a Graceful Shutdown. It stops accepting new HTTP connections, safely flushes ongoing requests, terminates WebSockets, and gracefully halts background tasks.
Programmatic Usage
If you are consuming the core framework directly in your own custom bootstrap script (instead of using the CLI), you can tap into the exact same graceful shutdown API:
import { createServer } from 'bro-framework/src/server.js';
// ...
const { server, shutdown } = await createServer(globalConfig, routesDir, db);
process.on('SIGTERM', async () => {
console.log("Shutting down...");
await shutdown();
console.log("Clean exit.");
process.exit(0);
});Graceful DB Teardown
If your injected database requires a manual teardown to close connections gracefully, define the onShutdown hook in your configuration:
import { defineConfig, z } from 'bro-framework';
export default defineConfig({
db: async () => {
// e.g. await mongoose.connect(...)
},
onShutdown: async (db) => {
console.log('Closing database connection...');
await db.close(); // Replace with your ORM's disconnect method
}
});Redis Integration
Setting a redisUrl will automatically connect a Redis client, inject it into ctx.redis, auto-scale your WebSockets via the adapter, and upgrade your rate limiters and route caching to use distributed Redis stores instantly!
Testing Mode
If you are running integration tests (i.e. NODE_ENV=test) and omit the redisUrl, the framework automatically mounts an in-memory ioredis-mock instance. This allows your CI pipelines to safely test distributed caching and rate limiters without needing a live Redis server. (Note: Ensure ioredis-mock is installed as a devDependency).