@gibme/webserver
    Preparing search index...

    @gibme/webserver

    @gibme/webserver

    A batteries-included Express.js v5 wrapper that provides an opinionated HTTP/HTTPS server with WebSocket support, session management, authorization parsing, and more.

    • Node.js >= 22
    yarn add @gibme/webserver
    # or
    npm install @gibme/webserver
    import WebServer, { Logger } from '@gibme/webserver';

    const app = WebServer({ port: 8080 });

    app.get('/', (_request, response) => {
    return response.json({ success: true });
    });

    app.ws('/wss', (socket) => {
    socket.on('message', msg => socket.send(msg));
    });

    await app.start();

    Logger.info('Listening on: %s', app.url);
    • Automatic request body parsing (JSON, URL-encoded, raw, text, XML)
    • Authorization header decoding (Basic, Bearer, JWT)
    • WebSocket support via .ws() routes
    • Session support with an in-memory store
    • Cookie parsing and signing
    • Protected routes with pluggable authentication
    • Request ID injection (X-Request-ID)
    • Response time tracking (X-Response-Time)
    • Client IP resolution through proxies and Cloudflare
    • Compression, Helmet, CORS, and CSP middleware
    • Optional route parameters (:id?)
    • Cloudflare Tunnel integration for development
    • Static file serving

    All options are optional with sensible defaults:

    const app = WebServer({
    host: '0.0.0.0',
    port: 8080,
    ssl: false, // or { certificate, privateKey }
    backlog: 511,
    bodyLimit: 2, // MB
    compression: true,
    corsOrigin: '*',
    helmet: false, // or HelmetOptions
    sessions: false, // or true or SessionOptions
    logging: false, // or true, 'full', or callback
    cookieSecret: ['insecure'],
    autoHandle404: true,
    autoHandleOptions: true,
    autoParseJSON: true,
    autoParseURLEncoded: true,
    autoParseRaw: true,
    autoParseText: true,
    autoParseXML: true,
    autoRecommendedHeaders: false,
    autoContentSecurityPolicyHeaders: false,
    autoStartCloudflared: false,
    suppressProcessErrors: true,
    xml: {}, // parser and validator options
    wsOptions: {} // ws.ServerOptions
    });

    The Authorization header is automatically parsed and available on every request:

    // Basic Auth: Authorization: Basic base64(user:pass)
    request.authorization?.basic?.username
    request.authorization?.basic?.password

    // Bearer Token: Authorization: Bearer <token>
    request.authorization?.bearer?.token

    // JWT: If the bearer token is a valid JWT structure
    request.authorization?.jwt?.header // { alg, typ }
    request.authorization?.jwt?.payload // decoded claims
    request.authorization?.jwt?.signature

    Use ProtectedRouter() to build a mountable Express Router whose every route is gated by a pluggable authentication provider. The provider is consulted on each request, so calling setAuthenticationProvider after registering routes updates auth for all of them:

    import WebServer, { ProtectedRouter } from '@gibme/webserver';

    const app = WebServer();
    const adminRouter = ProtectedRouter();

    adminRouter.setAuthenticationProvider(async (request) => {
    return request.authorization?.bearer?.token === 'secret';
    // return true to allow, false to deny (401)
    // or return { statusCode: 403, message: 'Forbidden' }
    });

    adminRouter.get('/admin', (_request, response) => {
    return response.json({ admin: true });
    });

    app.use(adminRouter); // mount at root
    // or: app.use('/api', adminRouter); // mount at a prefix

    Because ProtectedRouter() returns a real express.Router, all router methods are available (get, post, put, patch, delete, head, options, route, use, etc.) and instances can be nested or reused across apps.

    Register WebSocket handlers with Express-style routing:

    app.ws('/chat', (socket, request, next) => {
    socket.on('message', msg => socket.send(msg));
    });

    // With route parameters
    app.ws('/room/:id', (socket, request) => {
    const { id } = request.params;
    socket.send(`Joined room ${id}`);
    });

    WebSocket support can also be added to routers:

    import WebServer, { Router } from '@gibme/webserver';

    const router = Router();
    app.wsApplyTo(router, '/api');

    router.ws('/events', (socket) => { /* ... */ });
    app.use('/api', router);

    Enable in-memory sessions backed by node-cache:

    const app = WebServer({ sessions: true });

    app.post('/login', (request, response) => {
    request.session.user = request.body;
    return response.status(200).send();
    });

    app.get('/profile', (request, response) => {
    return response.json(request.session.user ?? {});
    });

    Pass express-session options for fine-grained control:

    const app = WebServer({
    sessions: {
    secret: 'your-secret',
    cookie: { secure: true, maxAge: 86400000 }
    }
    });

    Routes with optional parameters (:id?) are automatically expanded into two registered routes:

    app.get('/users/:id?', handler);
    // Registers both /users and /users/:id

    This works on all routing methods and on Router() instances.

    Spin up a Cloudflare Tunnel for development and testing:

    const app = WebServer({ autoStartCloudflared: true });
    await app.start();
    Logger.info('Public URL: %s', app.tunnel.url);

    Or manage the tunnel manually:

    await app.tunnel.install();
    await app.tunnel.start();
    console.log(app.tunnel.url); // https://xxxxx.trycloudflare.com
    console.log(app.tunnel.connections);
    await app.tunnel.stop();
    app.static('/assets', './public');
    
    // Basic request logging
    const app = WebServer({ logging: true });

    // Full logging (includes headers and body)
    const app = WebServer({ logging: 'full' });

    // Custom callback
    const app = WebServer({
    logging: async (entry) => {
    await saveToDatabase(entry);
    }
    });

    Every request is automatically augmented with:

    Property Type Description
    request.id string Unique request UUID
    request.remoteIp string Client IP (resolved through proxies/Cloudflare)
    request.time_elapsed number Response time in milliseconds
    request.authorization object Parsed authorization header
    request.cookies object Parsed cookies
    request.signedCookies object Verified signed cookies
    const app = WebServer({
    ssl: {
    certificate: '/path/to/cert.pem',
    privateKey: '/path/to/key.pem'
    }
    });

    Both file paths (strings) and Buffers are accepted.

    import WebServer, { Logger, Router, multer } from '@gibme/webserver';
    import type { Request, Response } from '@gibme/webserver';

    https://gibme-npm.github.io/webserver/

    MIT