http-status-lite
v2.3.0
Published
Tiny, standards-backed, type-safe HTTP status codes for Node.js and browsers
Maintainers
Readme
http-status-lite
Tiny, standards-backed, type-safe HTTP status codes for Node.js and browsers.
Why use it?
- Exact
HttpStatusCodeandHttpStatusNameunions generated from one registry snapshot - Literal-preserving lookups:
getStatus(404).nameis typed as'NOT_FOUND' - Named constants and small subpath exports for effective tree-shaking
- Runtime parsing, validation, and type guards for untrusted values
- Explicit IANA lifecycle metadata in an optional entry point
- ESM, CommonJS, Node.js, and browser support with no runtime dependencies
- Compatibility with the original
httpStatusLitenamespace
Install
npm install http-status-liteQuick start
import { Status, getReasonPhrase, getStatus, isStatusCode, isSuccess } from 'http-status-lite';
Status.OK; // 200
Status.NOT_FOUND; // 404
getReasonPhrase(404); // 'Not Found'
getStatus(404); // { code: 404, name: 'NOT_FOUND', message: 'Not Found' }
isSuccess(204); // true
isStatusCode(404); // trueLiteral inputs keep literal outputs:
const status = getStatus(404);
// typeof status.name is 'NOT_FOUND', not string
// typeof status.message is 'Not Found', not stringAPI
Constants
import { NOT_FOUND, OK, Status } from 'http-status-lite';
OK; // 200
NOT_FOUND; // 404
Status.CREATED; // 201For a constants-only bundle:
import { NOT_FOUND } from 'http-status-lite/codes';Lookups
import { getReasonPhrase, getStatus, getStatusCode, getStatusName } from 'http-status-lite';
getStatus(404); // complete entry
getStatusCode('NOT_FOUND'); // 404
getStatusName(404); // 'NOT_FOUND'
getReasonPhrase(404); // 'Not Found'
getStatus(499); // nullParsing and validation
import { assertStatusCode, isStatusCode, isStatusName, parseStatusCode } from 'http-status-lite';
parseStatusCode('404'); // 404
parseStatusCode('499'); // null: not a known entry
isStatusCode(404); // true, and narrows the value
isStatusName('NOT_FOUND'); // true, and narrows the value
assertStatusCode(value); // narrows or throws TypeErrorRange predicates
import {
getCategory,
isClientError,
isError,
isInformational,
isRedirect,
isServerError,
isSuccess,
} from 'http-status-lite/predicates';Range predicates classify any integer in the HTTP range. Registry validation is intentionally separate:
isClientError(499); // true: it is in the 4xx range
isStatusCode(499); // false: it is not a represented registry entry
getCategory(499); // '4xx'Registry metadata
Metadata has its own entry point so references and lifecycle data do not increase the core bundle:
import { getStatusMetadata } from 'http-status-lite/metadata';
getStatusMetadata(104);
// {
// code: 104,
// name: 'UPLOAD_RESUMPTION_SUPPORTED',
// message: 'Upload Resumption Supported',
// reference: 'draft-ietf-httpbis-resumable-upload-05',
// registryStatus: 'temporary',
// category: '1xx'
// }Lifecycle values are permanent, temporary, unused, or obsolete. Code 418 remains available as IM_A_TEAPOT for developer compatibility while metadata correctly identifies its current IANA state as unused.
Types
import type {
HttpStatusCategory,
HttpStatusCode,
HttpStatusEntry,
HttpStatusName,
} from 'http-status-lite';
const code: HttpStatusCode = 404;
const name: HttpStatusName = 'NOT_FOUND';Invalid known-code assignments fail during compilation:
const code: HttpStatusCode = 499; // TypeScript errorCommon recipes
Fetch
import { isClientError, isServerError } from 'http-status-lite';
const response = await fetch(url);
if (isClientError(response.status)) throw new Error('The request was rejected');
if (isServerError(response.status)) throw new Error('The service failed');Express, Fastify, Hono, or Next.js
The constants are framework-independent:
import { Status } from 'http-status-lite';
return new Response(JSON.stringify(data), { status: Status.CREATED });
// Express: res.status(Status.CREATED).json(data)
// Fastify: reply.code(Status.CREATED).send(data)
// Hono: return c.json(data, Status.CREATED)Validate an external value
import { parseStatusCode } from 'http-status-lite';
const status = parseStatusCode(process.env.EXPECTED_STATUS);
if (status === null) throw new Error('EXPECTED_STATUS must be a known HTTP status code');Compatibility and migration
The original namespace remains supported:
import { httpStatusLite } from 'http-status-lite';
httpStatusLite.OK; // 200
httpStatusLite.NOT_FOUND_MESSAGE; // 'Not Found'
httpStatusLite[404]; // 'NOT_FOUND'
httpStatusLite.UNPROCESSABLE_ENTITY; // 422, legacy alias
httpStatusLite.PAYLOAD_TOO_LARGE; // 413, legacy aliasRFC 9110 renamed Payload Too Large to Content Too Large and Unprocessable Entity to Unprocessable Content. New code should use CONTENT_TOO_LARGE and UNPROCESSABLE_CONTENT; the previous names remain on httpStatusLite.
Registry maintenance
registry/statuses.json is the reviewable source snapshot. Generated TypeScript must not be edited directly:
npm run generate
npm run generate:check
npm run registry:update # fetch the latest official IANA CSV, then regenerateThe snapshot follows the IANA HTTP Status Code Registry. Temporary and historical entries are represented explicitly instead of being silently treated as permanent standards.
A scheduled CI job compares the committed snapshot with IANA each month, making registry drift visible without putting a network request in package builds or application startup.
Development
npm ci
npm run checkThe full check covers linting, formatting, generation drift, compile-time type assertions, runtime behavior, bundle budgets, ESM/CommonJS exports, and the actual npm pack artifact.
