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

http-smart-response

v1.0.4

Published

Standardized, production-grade HTTP response middleware and helpers for Node.js (Express) and Bun

Readme

http-smart-response

Standardized, production-grade HTTP response middleware and response helper for Node.js (Express) and Bun / Fetch-compatible servers.

http-smart-response guarantees a consistent, structured JSON envelope across your entire API for both successful outputs and error conditions.


Features

  • Standardized JSON response templates for success and error states.
  • Clean integration with Express via res.responder.<method>().
  • Native Bun and standard Web Response support via responder.<method>().
  • Full coverage of production HTTP status codes (2xx, 3xx, 4xx, 5xx).
  • Contextual error payload formatting with error codes and validation details.
  • Comprehensive TypeScript declarations and typings included out of the box.

Installation

npm install http-smart-response
# or
bun add http-smart-response
# or
yarn add http-smart-response
# or
pnpm add http-smart-response

Standard Response Format

Success Response Envelope

{
  "success": true,
  "statusCode": 200,
  "message": "Resource retrieved successfully",
  "data": {
    "id": "usr_101",
    "name": "Alex Smith"
  },
  "meta": {
    "page": 1,
    "total": 100
  }
}
  • success (boolean): Always true for 2xx/3xx codes.
  • statusCode (number): The HTTP status code.
  • message (string): Human-readable status description or custom message.
  • data (any, optional): Main response payload.
  • meta (object, optional): Additional metadata like pagination or tracking headers.

Error Response Envelope

{
  "success": false,
  "statusCode": 400,
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Invalid request body",
    "details": [
      {
        "field": "email",
        "message": "Email must be a valid address"
      }
    ]
  }
}
  • success (boolean): Always false for 4xx/5xx codes.
  • statusCode (number): The HTTP status code.
  • error.code (string): Machine-readable error identifier (e.g. BAD_REQUEST, UNAUTHORIZED, or custom).
  • error.message (string): Description of what went wrong.
  • error.details (any, optional): Contextual debugging info or form validation error lists.

Usage

1. Express.js Middleware

Attach responderMiddleware to your Express application. The responder object is automatically mounted to res.responder.

import express from "express";
import { responderMiddleware } from "http-smart-response";

const app = express();
app.use(express.json());
app.use(responderMiddleware());

// 200 OK
app.get("/users/:id", (req, res) => {
  const user = { id: req.params.id, name: "Jane Doe" };
  return res.responder.ok(user, "User profile retrieved");
});

// 201 Created
app.post("/users", (req, res) => {
  const newUser = { id: "usr_99", ...req.body };
  return res.responder.created(newUser, "Account created successfully");
});

// 200 / 204 Deletions
app.delete("/users/:id", (req, res) => {
  return res.responder.deleted({ id: req.params.id });
});

// 400 Bad Request / Validation Failure
app.post("/login", (req, res) => {
  const { email, password } = req.body;
  if (!email || !password) {
    return res.responder.badRequest("Missing credentials", {
      errorCode: "INVALID_CREDENTIALS",
      details: { missing: ["email", "password"].filter(f => !req.body[f]) },
    });
  }

  // 401 Unauthorized
  if (password !== "secret") {
    return res.responder.unauthorized("Invalid email or password");
  }

  return res.responder.ok({ token: "jwt_sample_token" });
});

// 404 Not Found
app.get("/items/:id", (req, res) => {
  return res.responder.notFound("The requested item does not exist", {
    errorCode: "ITEM_NOT_FOUND",
  });
});

// 500 Internal Server Error
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
  return res.responder.internalServerError(err.message, {
    errorCode: "INTERNAL_SERVER_ERROR",
  });
});

app.listen(3000, () => {
  console.log("Server listening on port 3000");
});

2. Bun Native HTTP Server

Bun supports web standard Response objects natively. Import the pre-configured responder instance:

import { responder } from "http-smart-response";

Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);

    if (url.pathname === "/health") {
      return responder.ok({ status: "healthy", uptime: process.uptime() });
    }

    if (url.pathname === "/api/products" && req.method === "POST") {
      return responder.created({ id: 1, name: "Product A" });
    }

    if (url.pathname === "/api/admin") {
      return responder.forbidden("Access denied: Administrator privileges required", {
        errorCode: "INSUFFICIENT_PERMISSIONS",
      });
    }

    return responder.notFound("Route not found");
  },
});

3. Standalone Express Adapter (createResponder)

If you prefer not to register global middleware, you can wrap the Express res object directly:

import express from "express";
import { createResponder } from "http-smart-response";

const app = express();

app.get("/data", (req, res) => {
  const r = createResponder(res);
  return r.ok({ message: "Hello World" });
});

API Method Reference

Success Methods (2xx)

| Method | Status Code | Default Message | Typical Payload | |---|---|---|---| | ok(data?, options?) | 200 | "Success" | Any response data | | created(data?, options?) | 201 | "Resource created successfully" | Newly created entity | | accepted(data?, options?) | 202 | "Request accepted for processing" | Async task metadata / job ID | | noContent(headers?) | 204 | Empty body | None | | deleted(data?, options?) | 200 | "Resource deleted successfully" | Deleted ID or confirmation info |

Redirection Methods (3xx)

| Method | Status Code | Notes | |---|---|---| | movedPermanently(url, options?) | 301 | Sets Location header | | found(url, options?) | 302 | Sets Location header | | seeOther(url, options?) | 303 | Sets Location header | | notModified(headers?) | 304 | Empty body | | temporaryRedirect(url, options?) | 307 | Sets Location header | | permanentRedirect(url, options?) | 308 | Sets Location header |

Client Error Methods (4xx)

| Method | Status Code | Default Error Code | Description | |---|---|---|---| | badRequest(msg?, options?) | 400 | BAD_REQUEST | Malformed syntax or invalid payload | | unauthorized(msg?, options?) | 401 | UNAUTHORIZED | Authentication missing or failed | | paymentRequired(msg?, options?) | 402 | PAYMENT_REQUIRED | Subscription or payment needed | | forbidden(msg?, options?) | 403 | FORBIDDEN | Authenticated but access denied | | notFound(msg?, options?) | 404 | NOT_FOUND | Resource could not be found | | methodNotAllowed(msg?, options?) | 405 | METHOD_NOT_ALLOWED | HTTP method not supported for route | | notAcceptable(msg?, options?) | 406 | NOT_ACCEPTABLE | Requested content negotiation failed | | requestTimeout(msg?, options?) | 408 | REQUEST_TIMEOUT | Server timed out waiting for request | | conflict(msg?, options?) | 409 | CONFLICT | State conflict (e.g. duplicate key) | | gone(msg?, options?) | 410 | GONE | Resource permanently deleted | | payloadTooLarge(msg?, options?) | 413 | PAYLOAD_TOO_LARGE | Upload or payload exceeds limit | | unsupportedMediaType(msg?, options?) | 415 | UNSUPPORTED_MEDIA_TYPE | Unsupported Content-Type | | unprocessableEntity(msg?, options?) | 422 | UNPROCESSABLE_ENTITY | Semantic or schema validation errors | | tooManyRequests(msg?, options?) | 429 | TOO_MANY_REQUESTS | Rate limit exceeded |

Server Error Methods (5xx)

| Method | Status Code | Default Error Code | |---|---|---| | internalServerError(msg?, options?) | 500 | INTERNAL_SERVER_ERROR | | notImplemented(msg?, options?) | 501 | NOT_IMPLEMENTED | | badGateway(msg?, options?) | 502 | BAD_GATEWAY | | serviceUnavailable(msg?, options?) | 503 | SERVICE_UNAVAILABLE | | gatewayTimeout(msg?, options?) | 504 | GATEWAY_TIMEOUT |

Custom Status Method

| Method | Description | |---|---| | custom(statusCode, dataOrMessage?, options?) | Sends a formatted response with any arbitrary HTTP status code. |


Options Interface

Both success and error methods accept optional configuration:

interface ResponderOptions {
  message?: string;                 // Override default description
  meta?: Record<string, unknown>;    // Metadata (pagination, timestamp, traceId)
  errorCode?: string;               // Error code string (for 4xx/5xx)
  details?: unknown;                // Additional error info / validation list
  headers?: Record<string, string>; // Custom response headers
}

TypeScript Declarations

http-responder extends Express's native Response interface automatically when imported:

declare global {
  namespace Express {
    interface Response {
      responder: ExpressResponder;
    }
  }
}

License

MIT