npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vibe-gx

v2.0.0

Published

A lightweight, high-performance Node.js web framework with optional C++ optimizations.

Readme


📦 Installation

npm install vibe-gx

Optional: Build C++ Native Module

For maximum performance, build the optional C++ native module:

npm run build:native

If the build fails, Vibe automatically falls back to pure JavaScript with zero configuration.


🏆 Why Vibe?

| Metric | Vibe | Express | Fastify | | :------------------------ | :------------: | :-------: | :--------: | | JSON Performance | 14,687 RPS | 6,629 RPS | 11,289 RPS | | Install Size | ~280 KB | ~5 MB | ~4 MB | | Lines for Hello World | 3 | 5 | 6 | | Dependencies | 2 | 30+ | 15+ | | Built-in Clustering | ✅ | ❌ | ❌ | | Built-in Caching | ✅ | ❌ | ❌ | | C++ Optimizations | ✅ | ❌ | ❌ |

Vibe is faster than Fastify, simpler than Express, and 14-18x smaller than both.


⚡ Features

| Feature | Description | | :----------------------- | :--------------------------------------------------------- | | 🚀 C++ Native Module | JSON stringify & URL parsing in C++ | | 🎯 Hybrid Router | O(1) static + O(log n) Trie routing | | 🔌 Plugin System | Fastify-style register() with encapsulation | | 🎨 Decorators | Extend app, request, and response | | ⚡ Cluster Mode | Built-in multi-process scaling | | 💾 LRU Cache | Built-in response caching with ETag | | 🔗 Connection Pool | Generic pool for databases | | 📂 File Uploads | Multipart uploads with size/type validation | | 🌊 Streaming | Large file uploads without buffering | | 🔒 Security | Path traversal protection, body limits, error sanitization | | 🔄 Express Adapter | Use any Express middleware with adapt() |


🚀 Quick Start

import vibe from "vibe-gx";

const app = vibe();

// Direct value - no callback needed!
app.get("/", "Hello Vibe!");

// Auto JSON response - just return an object
app.get("/users/:id", (req) => ({ userId: req.params.id }));

app.listen(3000);

That's it. No res.send(), no res.json() - just return data.


📖 Core API

Routes

Vibe supports all standard HTTP methods with a clean, flexible syntax:

// String response
app.get("/", "Hello World");

// JSON response (just return an object)
app.get("/json", { message: "Hello" });

// Handler function with request access
app.get("/users/:id", (req) => ({ id: req.params.id }));

// Multiple route parameters
app.get("/posts/:postId/comments/:commentId", (req) => ({
  postId: req.params.postId,
  commentId: req.params.commentId,
}));

// With options (interceptors, file uploads)
app.post("/protected", { intercept: authCheck }, handler);

// All HTTP methods
app.get("/");
app.post("/");
app.put("/");
app.del("/"); // DELETE
app.patch("/");
app.head("/");

Query Parameters

// GET /search?q=hello&page=2
app.get("/search", (req) => ({
  query: req.query.q, // "hello"
  page: req.query.page, // "2"
}));

Request Body

app.post("/users", (req) => {
  const { name, email } = req.body;
  return { created: { name, email } };
});

🔌 Plugins (Fastify-style)

Plugins provide encapsulated route groups with optional prefixes:

// Register a plugin with prefix
await app.register(
  async (api) => {
    api.get("/status", { status: "ok" }); // GET /api/status
    api.get("/health", { healthy: true }); // GET /api/health

    // Plugins can have their own interceptors
    api.plugin((req, res) => {
      console.log(`[API] ${req.method} ${req.url}`);
    });
  },
  { prefix: "/api" },
);

// Nested plugins
await app.register(
  async (v1) => {
    v1.get("/users", { version: 1 }); // GET /api/v1/users
  },
  { prefix: "/api/v1" },
);

🛡️ Interceptors (Middleware)

Interceptors run before your handler. Return false to stop execution.

Single Interceptor

const authCheck = (req, res) => {
  if (!req.headers.authorization) {
    res.unauthorized("Token required");
    return false; // Stop execution
  }
  req.user = { id: 1 };
  return true; // Continue to handler
};

app.get("/protected", { intercept: authCheck }, (req) => {
  return { user: req.user };
});

Multiple Interceptors

app.get(
  "/admin",
  {
    intercept: [authCheck, adminCheck, rateLimiter],
  },
  handler,
);

Global Interceptors

// Applies to ALL routes
app.plugin((req, res) => {
  console.log(`${req.method} ${req.url}`);
});

🎨 Decorators

Extend app, request, or response with custom properties:

// App decorator - shared config
app.decorate("config", { env: "production", version: "1.0.0" });

// Access via app.decorators.config
app.get("/version", () => ({ version: app.decorators.config.version }));

// Request decorator - add to all requests
app.decorateRequest("timestamp", () => Date.now());

app.get("/time", (req) => ({ timestamp: req.timestamp }));

// Reply decorator - add methods to response
app.decorateReply("sendSuccess", function (data) {
  this.success(data);
});

📂 File Uploads

Vibe supports multipart file uploads with built-in validation.

Basic Upload

app.post("/upload", { media: { dest: "uploads" } }, (req) => {
>>>>>>> cpp-optimization
  return { files: req.files, body: req.body };
});

Media Options

cpp-optimization

app.post(
  "/upload",
  {
    media: {
      dest: "uploads", // Subfolder destination
      public: true, // Save inside public folder (default: true)
      maxSize: 5 * 1024 * 1024, // Max file size: 5MB
      allowedTypes: ["image/jpeg", "image/png", "image/*"], // Wildcards supported
    },
  },
  handler,
);

Uploaded File Object

// req.files contains:
[
  {
    filename: "image-a7x92b.png", // Saved filename (safe)
    originalName: "photo.png", // Original filename
    type: "image/png", // MIME type
    filePath: "/uploads/image-a7x92b.png", // Full path
    size: 102400, // Size in bytes
  },
];

Streaming Uploads (Large Files)

For large files, use streaming mode to avoid buffering in memory:

import fs from "fs";

app.post("/upload-large", { media: { streaming: true } }, (req) => {
  req.on("file", (name, stream, info) => {
    stream.pipe(fs.createWriteStream(`/uploads/${info.filename}`));
  });
  return { status: "uploading" };
});

Error Handling

  • 413 Payload Too Large - File exceeds maxSize
  • 415 Unsupported Media Type - File type not in allowedTypes

🔥 Scalability

Cluster Mode

Scale across all CPU cores automatically:

import vibe, { clusterize, isPrimary, getWorkerId } from "vibe-gx";

clusterize(
  () => {
    const app = vibe();
    app.get("/", `Hello from worker ${getWorkerId()}!`);
    app.listen(3000);
  },
  {
    workers: 4, // Number of workers (default: CPU count)
    restart: true, // Auto-restart crashed workers
    restartDelay: 1000, // Delay before restart (ms)
  },
);

LRU Cache

Built-in response caching with ETag support:

import vibe, { LRUCache, cacheMiddleware } from "vibe-gx";

const cache = new LRUCache({
  max: 1000, // Maximum entries
  ttl: 60000, // TTL in milliseconds (60 seconds)
});

app.get("/expensive", { intercept: cacheMiddleware(cache) }, async () => {
  // This only runs on cache MISS
  return await expensiveOperation();
});

// Manual cache operations
cache.set("key", { data: "value" });
cache.get("key"); // { value, expires, etag }
cache.delete("key");
cache.clear();

Connection Pool

Generic connection pool for databases:

import vibe, { createPool } from "vibe-gx";

const dbPool = createPool({
  create: async () => await connectToDatabase(),
  destroy: async (conn) => await conn.close(),
  validate: (conn) => conn.isAlive(),
  min: 2, // Minimum connections
  max: 10, // Maximum connections
  acquireTimeout: 30000, // Timeout to acquire (ms)
  idleTimeout: 60000, // Idle timeout (ms)
});

app.get("/users", async () => {
  return await dbPool.use(async (conn) => {
    return await conn.query("SELECT * FROM users");
  });
});

// Pool statistics
console.log(dbPool.stats);
// { available: 5, inUse: 2, waiting: 0, max: 10 }

// Cleanup on shutdown
process.on("SIGTERM", () => dbPool.close());

🔄 Express Middleware Adapter

Use any Express middleware with the adapter:

import { adapt } from "vibe-gx/utils/helpers/adapt.js";
import cors from "cors";
import helmet from "helmet";
import compression from "compression";

app.plugin(adapt(cors()));
app.plugin(adapt(helmet()));
app.plugin(adapt(compression()));

🔒 Security

Built-in protections:

| Feature | Status | | :-------------------------------------- | :----: | | Path traversal protection | ✅ | | File type validation | ✅ | | Body size limits (1MB JSON, 10MB files) | ✅ | | Error sanitization (production mode) | ✅ | | Safe filename generation | ✅ | | Port validation | ✅ |

Set NODE_ENV=production for secure error handling (stack traces hidden).

cpp-optimization


Interceptors (Middleware)

Interceptors run before your handler. Return false to stop execution.

Single Interceptor

const authCheck = (req, res) => {
  if (!req.headers.authorization) {
    res.unauthorized("Token required");
    return false;
  }
  req.user = { id: 1 };
  return true;
};

app.get("/protected", { intercept: authCheck }, (req) => {
  return { user: req.user };
});

Multiple Interceptors

app.get(
  "/admin",
  {
    intercept: [authCheck, adminCheck, rateLimiter],
  },
  handler,
);

Global Interceptors

// Applies to ALL routes
app.plugin((req, res) => {
  console.log(`${req.method} ${req.url}`);
});

Route Options

app.post(
  "/path",
  {
    intercept: authMiddleware, // Middleware function(s)
    media: {
      // File upload config
      dest: "uploads",
      maxSize: 10 * 1024 * 1024,
      allowedTypes: ["image/*"],
    },
  },
  handler,
);

🛠️ API Reference

Application

| Method | Description | | :----------------------------------------------- | :------------------- | | app.get/post/put/del/patch/head(path, handler) | Register route | | app.listen(port, host?, callback?) | Start server | | app.register(fn, { prefix }) | Register plugin | | app.plugin(fn) | Global interceptor | | app.decorate(name, value) | Add app property | | app.decorateRequest(name, value) | Add to all requests | | app.decorateReply(name, value) | Add to all responses | | app.setPublicFolder(path) | Set static folder | | app.logRoutes() | Log all routes |

Request (req)

| Property | Description | | :------------ | :------------------------- | | req.params | Route parameters (:id) | | req.query | Query string (?page=1) | | req.body | Parsed JSON/form body | | req.files | Uploaded files (multipart) | | req.ip | Client IP address | | req.method | HTTP method | | req.url | Request URL | | req.headers | Request headers |

Response (res)

| Method | Description | | :---------------------------------- | :--------------------------- | | res.json(data) | Send JSON | | res.send(data) | Send any response | | res.status(code) | Set status (chainable) | | res.redirect(url, code?) | Redirect (302) | | res.sendFile(path) | Send file from public folder | | res.sendAbsoluteFile(path, opts?) | Send file from any path | | res.sendHtml(filename) | Send HTML file | | res.success(data?, msg?) | 200 OK | | res.created(data?, msg?) | 201 Created | | res.badRequest(msg?, errors?) | 400 Bad Request | | res.unauthorized(msg?) | 401 Unauthorized | | res.forbidden(msg?) | 403 Forbidden | | res.notFound(msg?) | 404 Not Found | | res.conflict(msg?) | 409 Conflict | | res.serverError(err?) | 500 Server Error |

Cluster Utilities

| Function | Description | | :--------------------- | :---------------------------- | | clusterize(fn, opts) | Start in cluster mode | | isPrimary() | Check if primary process | | isWorker() | Check if worker process | | getWorkerId() | Get worker ID (0 for primary) | | getWorkerCount() | Get number of active workers |

Cache Utilities

| Class/Function | Description | | :-------------------------- | :------------------------ | | new LRUCache(opts) | Create LRU cache instance | | cacheMiddleware(cache) | Create cache interceptor | | LRUCache.key(method, url) | Generate cache key | | LRUCache.etag(value) | Generate ETag |

Pool Utilities

| Class/Function | Description | | :----------------- | :--------------------- | | createPool(opts) | Create connection pool | | pool.acquire() | Acquire resource | | pool.release(r) | Release resource | | pool.use(fn) | Use with auto-release | | pool.close() | Close pool | | pool.stats | Get pool statistics |


📊 Benchmarks

Run benchmarks yourself:

npm run benchmark

Tested with 5,000 requests, 50 concurrency:

Framework    | JSON RPS    | vs Express | vs Fastify
-------------|-------------|------------|------------
Vibe         | 14,687      | 2.2x ✅    | 1.3x ✅
Fastify      | 11,289      | 1.7x       | baseline
Express      | 6,629       | baseline   | 0.6x

🧪 Testing

# Run all tests
npm test

# Run comprehensive tests
npm run test:all

# Run benchmarks
npm run benchmark

📝 License

Part of the GeNeSix brand. Created by Nnamdi "Joe" Amaga.

MIT License.