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

@ahadpvt.v3/reqex

v2.0.2

Published

Zero-dependency, CPU-optimised, environment-aware HTTP request parser for Node.js, Edge Runtime, Cloudflare Workers, AWS Lambda, TCP and UDP

Downloads

459

Readme

@ahadpvt.v3/reqex

A zero-dependency, CPU-optimised, environment-aware HTTP request parser — and now also a TCP and UDP context builder — built as the request layer beneath a universal route dispatcher.

Parses body, query, cookies, and headers on demand. Two explicit body reading paths — buffered for small payloads, streaming for large ones. TCP and UDP connections get the same ergonomic ctx shape as HTTP so shared middleware works across all protocols without branching.


Installation

npm install @ahadpvt.v3/reqex

Import / Require

const { normalize, context, presets, adapters, adaptTcp, adaptUdp } = require("@ahadpvt.v3/reqex")

Quick Start

const { parse } = require("@ahadpvt.v3/reqex")

const ctx = await parse(req)

console.log(ctx.method)       // "POST"
console.log(ctx.path)         // "/users/42"
console.log(ctx.query)        // { page: "1" }
console.log(await ctx.body()) // { name: "Abdul" }

How It Works

raw request (any env)
      ↓
  normalize()     — detects env, produces NormalizedRequest
      ↓
  preset / parsers — parse only what you need
      ↓
  context         — rich object passed to your route handler

For a dispatcher, use normalize() + preset directly:

const nr  = normalize(req)
const ctx = await presets.api(nr)

console.log(ctx.query)
console.log(await ctx.body())

Body Reading — Two Paths

Two explicit, mutually exclusive paths. Once one is used the other throws clearly.

Buffered — small payloads

const body = await ctx.body()                          // auto detect
const body = await ctx.body({ type: "json" })          // override
const body = await ctx.body({ limit: 512 * 1024 })     // 512kb limit
const buf  = await ctx.rawBody()                       // raw Buffer

Streaming — large payloads

const stream = ctx.bodyStream()          // raw Readable — zero buffering
stream.pipe(destination)

for await (const part of ctx.parts()) { // streaming multipart
  if (part.file) part.stream.pipe(fs.createWriteStream(`/uploads/${part.filename}`))
  else console.log(part.name, part.value)
}

Consumption guard

await ctx.body()
ctx.bodyStream()   // throws BODY_ALREADY_CONSUMED

ctx.bodyConsumed   // boolean
ctx.bodyMode       // "buffered" | "streaming" | "streaming-multipart" | null

Presets

| Preset | Body | Pre-warms | Best for | |---|---|---|---| | minimal | not touched | query, cookies, headers | routing, redirects | | api | buffered json | query, headers | REST, GraphQL | | auth | buffered json | query, cookies, headers, auth() | login, OAuth | | form | buffered form/multipart | query, cookies, headers | HTML forms | | upload | not pre-consumed | headers | file uploads — use ctx.parts() | | proxy | not pre-consumed | headers | proxies — use ctx.bodyStream() | | webhook | buffered raw + signature | headers | Stripe, GitHub, Twilio | | full | buffered auto | everything | catch-all, debugging |


Context Object

ctx.method        // "POST"
ctx.url           // "https://example.com/api/users?page=1"
ctx.path          // "/api/users"
ctx.host          // "example.com"
ctx.subdomain     // "api" or null
ctx.ip            // real IP — CF > X-Real-IP > X-Forwarded-For > socket
ctx.env           // "node" | "edge" | "lambda" | "express"
ctx.raw           // original request, untouched
ctx.query         // { page: "1" } — lazy, cached
ctx.cookies       // { session: "abc" } — lazy, cached
ctx.headers       // enriched headers — lazy, cached
ctx.bodyConsumed  // boolean
ctx.bodyMode      // string | null

ctx.get("x-request-id")   // header, case-insensitive
ctx.is("json")            // content-type check
ctx.hasBody()             // true for POST/PUT/PATCH or content-length > 0
ctx.isPreflight()         // CORS preflight
ctx.isUpgrade()           // WebSocket upgrade
ctx.auth()                // { type: "Bearer", token: "..." } | null

await ctx.body(opts)      // buffered + parsed
await ctx.rawBody(opts)   // buffered raw Buffer
ctx.bodyStream()          // raw Readable
ctx.parts()               // async iterator — streaming multipart

TCP Context

For raw TCP, TLS, and Unix socket connections. Produced by adaptTcp(socket, data).

Has the same shape as HTTP ctx where safe — all HTTP-style accessors return safe empty values so shared middleware works across HTTP and TCP without branching.

const { adaptTcp } = require("@ahadpvt.v3/reqex")

net.createServer(socket => {
  socket.on("data", chunk => {
    const ctx = adaptTcp(socket, chunk)

    console.log(ctx.ip)     // "192.168.1.1"
    console.log(ctx.port)   // 54321
    console.log(ctx.id)     // "192.168.1.1:54321:1712345678000"
    console.log(ctx.env)    // "tcp"
    console.log(ctx.data)   // Buffer — raw chunk or decoded frame
    console.log(ctx.socket) // net.Socket
  })
})

Used internally by dispex.tcp(), dispex.tls(), and dispex.unix().


UDP Context

For UDP messages. Produced by adaptUdp(msg, rinfo, socket).

const { adaptUdp } = require("@ahadpvt.v3/reqex")

const server = dgram.createSocket("udp4")
server.on("message", (msg, rinfo) => {
  const ctx = adaptUdp(msg, rinfo, server)

  console.log(ctx.ip)     // sender IP
  console.log(ctx.port)   // sender port
  console.log(ctx.data)   // raw Buffer
  console.log(ctx.env)    // "udp"
})

Used internally by dispex.udp().


Environments

adapters.detect(req)       // auto
adapters.node(req)         // http.IncomingMessage
adapters.express(req)      // Express / Fastify
adapters.edge(req)         // Edge Runtime / CF Workers
adapters.lambda(event)     // AWS Lambda

Error Handling

try {
  const body = await ctx.body()
} catch (err) {
  if (err.isReqex) {
    switch (err.code) {
      case "BODY_TOO_LARGE":
      case "BODY_ALREADY_CONSUMED":
      case "INVALID_JSON":
      case "NO_BOUNDARY":
      case "STREAM_ERROR":
      case "REQUEST_ABORTED":
      case "INVALID_REQUEST":
      case "UNKNOWN_PRESET":
    }
  }
}

Constants

const { CONTENT_TYPE, DEFAULT_BODY_LIMIT, DEFAULT_UPLOAD_LIMIT } = require("@ahadpvt.v3/reqex")

CONTENT_TYPE.JSON    // "application/json"
CONTENT_TYPE.GRPC    // "application/grpc"

DEFAULT_BODY_LIMIT   // 1048576  (1mb)
DEFAULT_UPLOAD_LIMIT // 52428800 (50mb)

Runtime Adapter (Advanced)

You can inject runtime capabilities explicitly when running in constrained environments.

const { setRuntimeAdapter } = require("@ahadpvt.v3/reqex")

setRuntimeAdapter({
  Buffer,
  Readable,
  nextTick: (fn) => queueMicrotask(fn),
  reportError: (err, meta) => console.error("reqex runtime error", err, meta),
})

If a required capability is missing, reqex throws UNSUPPORTED_RUNTIME with an explicit message.


Testing

npm test
54 passed, 0 failed

License

MIT © Abdul Ahad