accepts
Higher-level HTTP content negotiation for Node.js, wrapping negotiator with type shorthands and charset, encoding, and language matching.
Repository Health
Technical Analysis
accepts is a small, focused Node.js library for HTTP content negotiation, extracted from the Koa framework for standalone use. It wraps the lower-level negotiator package with a friendlier API surface: types can be passed as MIME strings or file-extension shorthands like ‘json’ or ‘html’, and requests with no Accept header default sensibly instead of failing.
Widely depended upon in the npm ecosystem — it ships as part of Express’s dependency tree — accepts is one of the small, stable building blocks that make up Node’s HTTP server layer. It exposes methods for negotiating media types, charsets, encodings, and languages, each returning the client’s preferred match ordered by quality value.
What You Get
- A unified Accepts(req) constructor that wraps negotiator with a friendlier, higher-level API.
- Type shorthand support so callers can write accept.types(‘json’, ‘html’) instead of full MIME strings.
- Charset, encoding, and language negotiation methods returning ranked lists or single best matches.
- Graceful defaults: requests without an Accept header return the first offered type instead of erroring.
Common Use Cases
- Content-type branching in Express/Koa-style route handlers that respond with JSON, HTML, or plain text depending on what the client accepts.
- Building custom middleware that needs 406 Not Acceptable responses when no requested type matches.
- Negotiating gzip/deflate response encoding for compression middleware.
- Serving localized content by negotiating the client’s preferred language from Accept-Language.
Under The Hood
Architecture
accepts is a single-file CommonJS module built around one factory function, Accepts(req), that composes a negotiator instance from the request headers and layers a friendlier method surface on top — .type/.types, .charset/.charsets, .encoding/.encodings, and .language/.languages (aliased as .lang/.langs) — with small private helpers (extToMime, validMime) translating extension shorthands to MIME strings via the mime-types package before handing candidates to negotiator’s quality-value matching; the design is a thin adapter/composition layer over one dependency, so the entire library’s behavior is bounded by what negotiator already resolves.
Tech Stack
The runtime is plain, dependency-light CommonJS JavaScript with no build step, targeting Node.js 18+ and declaring exactly two runtime dependencies — mime-types and negotiator — with development tooling limited to Mocha/nyc for tests and ESLint’s standard config for linting, all wired into a GitHub Actions CI matrix that runs the suite across five active Node.js versions.
Code Quality
A dedicated test suite (charset.js, encoding.js, language.js, type.js) exercises each negotiation method using Mocha with leak-checking and bail-on-first-failure enabled, assertions rely on deep-equal, and the codebase is enforced by ESLint’s opinionated standard style with consistent camelCase naming and JSDoc-documented public/private boundaries; there is no static type system (plain JS, no TypeScript or JSDoc type annotations), and error handling favors returning false sentinels over throwing, which suits its role as a pure negotiation helper rather than an application framework.
API Design
The public API keeps its footprint deliberately small — one constructor and four negotiation methods, each offering both singular (“first match”) and plural (“ranked list”) variants under memorable aliases (.lang/.langs/.language/.languages) — and getting started requires a single require('accepts')(req) call with no configuration; documentation is thorough for the library’s scope (a fully worked README example, extensive inline JSDoc), though the design itself is a conventional negotiation wrapper rather than a novel approach.