http-status vs http-status-code vs http-status-codes vs statuses
Selecting the Right HTTP Status Code Utility for Node.js Applications
http-statushttp-status-codehttp-status-codesstatuses

Selecting the Right HTTP Status Code Utility for Node.js Applications

The packages http-status, http-status-code, http-status-codes, and statuses all provide mappings between HTTP status codes (integers) and their standard text phrases or constants. They solve the problem of avoiding "magic numbers" (like 404 or 500) in code, improving readability and reducing errors. While they share a common goal, they differ significantly in API design, maintenance status, and ecosystem integration. http-status-codes is the most feature-rich and widely adopted community standard, offering bidirectional lookups and extensive constants. statuses is a minimal, low-level utility often used internally by major frameworks like Express and Koa. http-status offers a class-based approach but sees less active evolution. http-status-code is an older, simpler alternative that is largely superseded by more robust options.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
http-status0483338 kB52 years agoBSD-3-Clause
http-status-code07-0-MIT
http-status-codes01,122223 kB323 years agoMIT
statuses028312.5 kB7a year agoMIT

HTTP Status Libraries: A Deep Dive into http-status-codes, statuses, http-status, and http-status-code

In professional Node.js development, hardcoding numbers like 404 or 500 is a recipe for confusion. We use libraries to map these integers to human-readable constants like NOT_FOUND or INTERNAL_SERVER_ERROR. While four main packages exist in the npm ecosystemβ€”http-status-codes, statuses, http-status, and http-status-codeβ€”they are not created equal. Some are built for high-level application logic, while others serve as tiny building blocks for frameworks.

This guide breaks down the technical differences, API styles, and real-world trade-offs to help you pick the right tool for your architecture.

πŸ—οΈ API Design Philosophy: Constants vs. Lookups

The most immediate difference is how these libraries expose data. Do you want named constants to use in your res.status() calls, or just a quick way to turn a number into a string?

http-status-codes is designed for developer experience. It exports a massive object of named constants. This allows for type-safe, self-documenting code where the intent is clear without memorizing numbers.

// http-status-codes
const { StatusCodes } = require('http-status-codes');

// Usage: Clear intent, no magic numbers
res.status(StatusCodes.NOT_FOUND).json({ error: 'Missing' });
res.status(StatusCodes.OK).send('Success');

statuses takes a minimalist approach. It does not export a list of constants for you to import. Instead, it acts as a function that accepts a code and returns the message. It is purely a lookup utility.

// statuses
const status = require('statuses');

// Usage: Get message from code
const message = status(404); // Returns "Not Found"

// It does NOT provide: status.NOT_FOUND constant

http-status uses a class-based or enum-like structure. It groups codes by category (Informational, Success, Redirection, etc.), which can be helpful if you need to logically group checks, though it adds verbosity.

// http-status
const HttpStatus = require('http-status');

// Usage: Access via class properties
res.status(HttpStatus.NOT_FOUND).send('Missing');

// Check category
if (code >= HttpStatus.BAD_REQUEST && code < HttpStatus.INTERNAL_SERVER_ERROR) {
  // Handle client errors
}

http-status-code provides a simple mapping object similar to http-status-codes but with a flatter structure and fewer features. It is often used as a direct dictionary.

// http-status-code
const statusCode = require('http-status-code');

// Usage: Direct property access
const code = statusCode['Not Found']; // Returns 404
const message = statusCode[404];      // Returns "Not Found"

πŸ” Bidirectional Lookups: Code to Phrase and Back

Real-world apps often need to convert in both directions: displaying a message to a user based on a code, or determining a code based on a string label.

http-status-codes excels here. It provides dedicated functions for both directions, handling edge cases and custom codes gracefully.

// http-status-codes
const { getStatusText, getStatusCode } = require('http-status-codes');

// Code -> Text
const text = getStatusText(403); // "Forbidden"

// Text -> Code
const code = getStatusCode('Forbidden'); // 403

statuses only supports Code -> Text. If you need the reverse, you must build your own map or use a different library. This keeps the package tiny but shifts the burden to you.

// statuses
const status = require('statuses');

// Code -> Text (Supported)
console.log(status(500)); // "Internal Server Error"

// Text -> Code (Not Supported natively)
// You would need to create a reverse map manually

http-status allows reverse lookups but often requires iterating through its internal structures or using specific helper methods that are less direct than http-status-codes.

// http-status
const HttpStatus = require('http-status');

// Often requires manual lookup or helper usage depending on version
// No simple single-function reverse lookup like getStatusText
const code = HttpStatus['FORBIDDEN']; 

http-status-code supports bidirectional access because it exposes the raw mapping object, but it lacks the helper functions that validate input or handle casing inconsistencies.

// http-status-code
const map = require('http-status-code');

// Code -> Text
const text = map[404]; 

// Text -> Code (Case sensitive and fragile)
const code = map['Not Found']; 

πŸ› οΈ Maintenance and Ecosystem Integration

Choosing a library isn't just about features; it's about longevity and trust. Is this package still updated? Do major frameworks rely on it?

statuses is the backbone of the Express.js and Koa ecosystems. It is maintained by the Node.js foundation collaborators and is extremely stable. It rarely changes because its job is simple and critical. If you are writing middleware for Express, this is likely already in your dependency tree.

// Used internally by Express/Koa
// Highly stable, low-level dependency
// Best for: Framework authors, minimalists

http-status-codes is the community favorite for application developers. It has frequent updates to include new or obscure HTTP codes and has a very large adoption rate in modern TypeScript and JavaScript projects. It is the safest choice for new startups and enterprise apps alike.

// Community standard for apps
// Active maintenance, rich typescript definitions
// Best for: Application logic, API development

http-status and http-status-code are older packages. While they still work, their update frequency is lower, and they lack the modern TypeScript support and ergonomic features found in http-status-codes. They are perfectly functional but offer less value for new projects.

// Legacy / Stable but less active
// Best for: Maintaining existing codebases using them
// Avoid for: New greenfield projects unless specific features are needed

⚑ Performance and Bundle Size

For most server-side Node.js applications, the performance difference between these libraries is negligible. However, in edge computing (like Cloudflare Workers) or bundled browser environments, every byte counts.

statuses is the undisputed winner for size. It contains only the data needed for standard codes and nothing else. There is no bloat.

// statuses: Minimal footprint
// Ideal for serverless functions where cold start time matters

http-status-codes is larger because it includes extra helper functions, aliases, and a more complex structure to support its rich API. For 99% of backend services, this trade-off is worth the improved developer experience.

// http-status-codes: Larger but feature-rich
// The extra bytes buy you significant DX improvements

πŸ“Š Summary of Differences

Featurehttp-status-codesstatuseshttp-statushttp-status-code
Primary UseApp DevelopmentFramework InternalsLegacy / SpecificSimple Lookup
Constantsβœ… Rich (StatusCodes.OK)❌ Noneβœ… Class-basedβœ… Basic Object
Reverse Lookupβœ… getStatusCode()❌ No⚠️ Manual/Complex⚠️ Direct Access
Maintenance🟒 High🟒 High (Core)🟑 Moderate🟑 Low
Bundle SizeMediumTinyMediumSmall

πŸ’‘ Final Recommendation

For most professional frontend and backend developers, http-status-codes is the clear winner. It strikes the perfect balance between features, maintainability, and ease of use. The ability to write StatusCodes.BAD_GATEWAY instead of 502 makes your code self-documenting and less prone to typos.

Reserve statuses for special cases: if you are building a library yourself, writing high-performance middleware, or strictly optimizing for minimal dependencies. It is a tool for architects, not necessarily for daily application logic.

Avoid starting new projects with http-status or http-status-code unless you have a specific constraint. The ecosystem has moved toward http-status-codes for good reason: it simply makes development faster and safer.

How to Choose: http-status vs http-status-code vs http-status-codes vs statuses

  • http-status:

    Choose http-status only if you are maintaining a legacy codebase that already relies on its specific class-based structure or if you require its particular set of helper methods for categorizing status codes (e.g., checking if a code is 'informational'). For new greenfield projects, more modern alternatives are generally preferred.

  • http-status-code:

    Avoid choosing http-status-code for new projects. It is an older package with limited features and less active maintenance compared to http-status-codes. Unless you are constrained by a specific legacy dependency tree that requires this exact package name, http-status-codes is a superior drop-in replacement with better long-term support.

  • http-status-codes:

    Choose http-status-codes for most application-level development where you need a rich set of named constants (e.g., StatusCodes.BAD_REQUEST) and bidirectional lookups (code to phrase and vice versa). It is the safest bet for new projects due to its active maintenance, comprehensive coverage of standard and custom codes, and widespread adoption in the community.

  • statuses:

    Choose statuses if you are building low-level middleware, framework internals, or performance-critical tools where minimal bundle size and zero dependencies are paramount. It provides a simple, fast lookup from code to message but lacks the extensive constant definitions and reverse lookup features of larger libraries.

README for http-status

HTTP Status codes for Node.js

Utility to interact with HTTP status codes.

Migration to v2.x

Version 2 is a migration of the library to ESM modules and TypeScript. The API remains the same. The build system generates both ESM and CommonJS exports.

For ESM users, the import remains the same.

import status from "http-status";
// Or
import { status } from "http-status";

For CommonJs users, update the require statement.

const { status } = require("http-status");
// Or
const { default: status } = require("http-status");

Usage

Once you import or require this module, you may call it with either an HTTP code or a status name. With an HTTP code, you will get the status name while with a status name you will get an HTTP code or some complementary information.

For example, status[418] return IM_A_TEAPOT while status.IM_A_TEAPOT return "I'm a teapot" and status.IM_A_TEAPOT_CODE returns 418.

The package is written in TypeScript and built for CommonJS and ESM.

HTTP Status codes

HTTP code names, information, and classes are respectively accessible with the property {code}_NAME, {code}_MESSAGE and {code}_CLASS. This includes all statuses in the IANA HTTP Status Code Registry, with the only addition being 418 I'm a teapot.

Extra codes

Extra status code are also made available that are not defined in the IANA registry, but used by popular softwares. They are grouped by category. Specific properties are exported by http-status under the property extra followed by the category name. Also, extra codes are merge with regular status codes and made available as modules available inside http-status/lib/{category}.

Available categories are:

unofficial
This represent a list of codes which are not specified by any standard.
iis
Microsoft's Internet Information Services (IIS) web server expands the 4xx error class to signal errors with the client's request.
nginx
The NGINX web server software expands the 4xx error class to signal issues with the client's request.
cloudflare
Cloudflare's reverse proxy service expands the 5xx error class to signal issues with the origin server.

They are accessible throught the status.extra[category] property. It is also possible to import one of the category with import status from "http-status/<category>" or const status = require("http-status/")`. In the later case, all the categories properties are merge with the common HTTP statuses.

HTTP Status code classes

In addition to HTTP status codes, this module also contains status code classes under the classes property. Similar to HTTP codes, you can access class names and messages with the property {class}_NAME and {class}_MESSAGE.

API organization

The API is structured as follows:

100
100_NAME
100_MESSAGE
100_CLASS
CONTINUE
101
101_NAME
101_MESSAGE
101_CLASS
SWITCHING_PROTOCOLS
…
classes.
β”œβ”€β”€ 1xx
β”œβ”€β”€ 1xx_NAME
β”œβ”€β”€ 1xx_MESSAGE
β”œβ”€β”€ INFORMATIONAL
β”œβ”€β”€ 2xx
β”œβ”€β”€ 2xx_NAME
β”œβ”€β”€ 2xx_MESSAGE
β”œβ”€β”€ SUCCESSFUL
β”œβ”€β”€ …
extra.
β”œβ”€β”€ unofficial.
β”‚   β”œβ”€β”€ 103
β”‚   β”œβ”€β”€ 103_NAME
β”‚   β”œβ”€β”€ 103_MESSAGE
β”‚   β”œβ”€β”€ 103_CLASS
β”‚   β”œβ”€β”€ CHECKPOINT
β”‚   β”œβ”€β”€ …
β”œβ”€β”€ iis.
β”‚   β”œβ”€β”€ 440
β”‚   β”œβ”€β”€ 440_NAME
β”‚   β”œβ”€β”€ 440_MESSAGE
β”‚   β”œβ”€β”€ 440_CLASS
β”‚   β”œβ”€β”€ LOGIN_TIME_OUT
β”‚   β”œβ”€β”€ …
β”œβ”€β”€ nginx.
β”‚   β”œβ”€β”€ 444
β”‚   β”œβ”€β”€ 444_NAME
β”‚   β”œβ”€β”€ 444_MESSAGE
β”‚   β”œβ”€β”€ 444_CLASS
β”‚   β”œβ”€β”€ NO_RESPONSE
β”‚   β”œβ”€β”€ …
β”œβ”€β”€ cloudflare.
β”‚   β”œβ”€β”€ 520
β”‚   β”œβ”€β”€ 520_NAME
β”‚   β”œβ”€β”€ 520_MESSAGE
β”‚   β”œβ”€β”€ 520_CLASS
β”‚   β”œβ”€β”€ UNKNOWN_ERROR
β”‚   β”œβ”€β”€ …

For additional information, please refer to original code.

Example API usage

The api example illustrate how to access status names by code and number and how to extra various associated informations.

import status from "http-status";

console.info(status.INTERNAL_SERVER_ERROR);
// Output: 500

console.info(status[500]);
console.info(status[status.INTERNAL_SERVER_ERROR]);
// Both output: "Internal Server Error"

console.info(status["500_NAME"]);
console.info(status[`${status.INTERNAL_SERVER_ERROR}_NAME`]);
// Both output: "INTERNAL_SERVER_ERROR"

console.info(status["500_MESSAGE"]);
console.info(status[`${status.INTERNAL_SERVER_ERROR}_MESSAGE`]);
// Both output: "A generic error message, given when an unexpected condition was encountered and no more specific message is suitable."

console.info(status["500_CLASS"]);
console.info(status[`${status.INTERNAL_SERVER_ERROR}_CLASS`]);
// Both output: "5xx"

Example using classes

import status from "http-status";

const responseCode = status.INTERNAL_SERVER_ERROR;

switch (status[`${responseCode}_CLASS`]) {
  case status.classes.INFORMATIONAL:
    // The responseCode is 1xx
    break;
  case status.classes.SUCCESSFUL:
    // The responseCode is 2xx
    break;
  case status.classes.REDIRECTION:
    // The responseCode is 3xx
    break;
  case status.classes.CLIENT_ERROR:
    // The responseCode is 4xx
    break;
  case status.classes.SERVER_ERROR:
    // The responseCode is 5xx
    break;

  default:
    // Unknown
    break;
}

Example using the extra property

// Accessing property from the NGINX category
import status from "http-status";
console.info(status.extra.nginx.NO_RESPONSE);

// Accessing default HTTP status merged with NGINX status
import status from "http-status/lib/nginx";
console.info(status.IM_A_TEAPOT);
console.info(status.NO_RESPONSE);

Example integrating Express

The express example integrate the library with a real wold usage.

import express from "express";
import redis from "redis";
import status from "http-status";

// New Express HTTP server
const app = express.createServer();
// Regster a route
app.get("/", (req, res) => {
  const client = redis.createClient();
  client.ping((err, msg) => {
    if (err) {
      return res.send(status.INTERNAL_SERVER_ERROR);
    }
    res.send(msg, status.OK);
  });
});
// Start the HTTP server
app.listen(3000);

Contributors

The project is sponsored by Adaltas based in Paris, France. Adaltas offers support and consulting on distributed systems, big data and open source.

Developers

To automatically generate a new version:

npm run release

Package publication is handled by the CI/CD with GitHub action.