negotiator

HTTP content negotiator for Node.js — picks the best media type, language, charset, or encoding

Library
npm
v1.0.0
383stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
59/100Fair
Development Activity56
Maintenance28
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture78
Code Quality82
Innovation65
Learning Curve85

Negotiator is a small, dependency-free Node.js library that implements HTTP content negotiation: given a request’s Accept, Accept-Language, Accept-Charset, and Accept-Encoding headers, it ranks or selects the best match from a list of options your server supports. It correctly parses quality-value (q=) weighted header syntax so servers can respect client preference ordering rather than guessing.

Maintained under the jshttp organization (the same group behind accepts, body-parser, and other Express-ecosystem middleware), Negotiator is the low-level engine that higher-level libraries like accepts build on top of to add MIME-type validation and a friendlier API. It has no runtime dependencies and is used transitively by a large share of the Node.js web-framework ecosystem, including Express itself.

What You Get

  • mediaType() / mediaTypes() for Accept header negotiation, with and without a list of available media types
  • language() / languages() for Accept-Language negotiation
  • charset() / charsets() for Accept-Charset negotiation
  • encoding() / encodings() for Accept-Encoding negotiation, including a preferred option to break ties between equal-quality encodings
  • Correct RFC-compliant handling of q= quality values and wildcard (*) matching

Common Use Cases

  • Serving different response formats (JSON, HTML, XML) from the same route based on the client’s Accept header
  • Choosing which compression encoding (gzip, br, identity) to apply to a response body
  • Selecting a localized response language from a set of supported locales based on Accept-Language
  • Building higher-level content-negotiation middleware (as the accepts package does) on top of a well-tested primitive

Under The Hood

Architecture - index.js exposes a Negotiator constructor that wraps a request object’s headers, delegating each negotiation dimension to a dedicated module in lib/ (mediaType.js, language.js, charset.js, encoding.js), each of which parses the relevant header into weighted tokens and sorts/filters them against an optional list of server-supported values. Tech Stack - Plain, dependency-free JavaScript (CommonJS) targeting Node.js >=18, with no runtime dependencies at all — only eslint, mocha, and nyc as devDependencies for linting, testing, and coverage. Code Quality - The test/ directory mirrors the lib/ structure with one spec file per negotiation dimension (mediaType, language, charset, encoding), run via mocha --check-leaks with nyc coverage reporting in CI, reflecting the library’s role as a foundational dependency that many other packages trust for correctness. API Design - The thing()/things() naming convention (singular returns the best match, plural returns a ranked list) is consistent across all four negotiation dimensions, and calling each method with no arguments returns the client’s raw ranked preferences — a small, predictable surface that’s easy to build higher-level abstractions on top of.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search