Skip to content

Express Drop-in Replacement & Middleware Compatibility

Velociradix provides seamless 100% backward-compatibility for the entire Express.js ecosystem both as a Drop-in Replacement (velociradix/express) and via app.useExpress().

🏎️ 1. Drop-in Replacement (velociradix/express)

Upgrade legacy Express codebases instantly by changing only the import line:

javascript
// Replace: import express from 'express';
import express from 'velociradix/express';

const app = express();

app.use(express.json());

app.get('/api/users', (req, res) => {
  res.json([{ id: 1, name: 'Alice' }]);
});

app.listen(3000, () => {
  console.log('Running legacy Express code on Velociradix C++ Engine!');
});

🚀 2. Granular Express Bridge (app.useExpress)

js
import { createApp } from 'velociradix';
import cors from 'cors';
import morgan from 'morgan';
import helmet from 'helmet';
import cookieParser from 'cookie-parser';

const app = createApp();

// 1. HTTP Request Logger (Morgan) - Full EventEmitter & timing support
app.useExpress(morgan('combined'));

// 2. Security Headers (Helmet)
app.useExpress(helmet());

// 3. CORS Configuration
app.useExpress(cors({ origin: '*' }));

// 4. Cookie Parsing
app.useExpress(cookieParser('secret-key'));

// 5. Mount Existing Express Router Instances
import { Router } from 'express';
const router = Router();
router.get('/users', (req, res) => res.json([{ id: 1, name: 'Alice' }]));

app.useExpressRouter('/v1', router);

// 6. Custom Express Middleware using standard req / res APIs
app.useExpress((req, res, next) => {
  res.setHeader('X-Powered-By', 'Velociradix + Express Engine Bridge');
  req.customTimestamp = Date.now();
  next();
});

app.get('/api', (ctx) => {
  return { 
    message: 'Running with Express 100% API Compatibility Layer',
    timestamp: ctx.req.customTimestamp 
  };
});

app.listen(3000, () => {
  console.log('Server running with Express compatibility at http://localhost:3000');
});

🛠️ Supported Express APIs & Features

The app.useExpress(fn) bridge transparently wraps and maps Velociradix's internal request context into a complete, spec-compliant Express req and res pair:

📥 Express Request (req) Compatibility

  • Request Metadata: req.url, req.originalUrl, req.baseUrl, req.path, req.method
  • Data Containers: req.params, req.query, req.body, req.cookies, req.signedCookies
  • Network & IP: req.ip, req.ips, req.protocol, req.secure, req.hostname, req.subdomains, req.xhr
  • Sockets & Timing: req.socket, req.connection, req._startTime, req.fresh, req.stale
  • Helper Methods:
    • req.get(headerName) / req.header(headerName)
    • req.is(type)
    • req.accepts(), req.acceptsEncodings(), req.acceptsCharsets(), req.acceptsLanguages()
    • req.param(name, defaultValue)

📤 Express Response (res) Compatibility

  • Response Metadata & Locals: res.statusCode, res.statusMessage, res.headersSent, res.locals, res.app, res.req, res._startTime
  • Header Operations: res.setHeader(), res.getHeader(), res.get(), res.getHeaders(), res.getHeaderNames(), res.hasHeader(), res.removeHeader(), res.header(), res.set(), res.append(), res.vary()
  • Cookies & Clearing: res.cookie(name, val, options), res.clearCookie(name, options)
  • Sending & Formatting:
    • res.status(code) / res.sendStatus(code)
    • res.send(body) / res.json(body) / res.jsonp(body) / res.text(body) / res.html(body)
    • res.type(type) / res.contentType(type)
    • res.location(url) / res.redirect([status], url)
    • res.end() / res.write() / res.writeHead()
  • Files & Attachments: res.sendFile(path, opts), res.download(path, filename, opts), res.attachment(filename), res.links(), res.format()
  • Event Emitter Suite: Full res.on(), res.once(), res.emit(), and res.removeListener() implementation — emits the 'finish' event upon response dispatch for logging & metrics tools (such as Morgan, Response-Time, & APM loggers).

🎧 Leveraging Response & App Event Listeners

You can listen to lifecycle events both on individual Express response instances (res.on) and globally on the Velociradix application bus (app.on):

1. Response Event Listeners (res.on('finish'))

Listen for response completion inside custom Express middlewares to log metrics or execute cleanup:

js
app.useExpress((req, res, next) => {
  const startTime = Date.now();

  // Triggered when response is fully sent to client
  res.on('finish', () => {
    const duration = Date.now() - startTime;
    console.log(`[Metrics] ${req.method} ${req.originalUrl} - Status: ${res.statusCode} (${duration}ms)`);
  });

  next();
});

2. Global Application Lifecycle Listeners (app.on)

Velociradix provides event-driven bus handlers for global observability:

js
// 1. Request Received Event
app.on('request', (ctx) => {
  console.log(`[Global Event] Request received for: ${ctx.req.path}`);
});

// 2. Response Sent Event
app.on('response', (ctx) => {
  console.log(`[Global Event] Response dispatched with status: ${ctx.statusCode}`);
});

// 3. Error Event
app.on('error', (err, ctx) => {
  console.error(`[Global Error Event] Exception on ${ctx.req.path}: ${err.message}`);
});

⚡ Performance Note

app.useExpress() introduces zero extra allocations overhead by reusing pooled context layers. It allows you to run high-performance C++ backend routing alongside your favorite Express middlewares!

Released under the MIT License.