or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-negotiator

HTTP content negotiation library for Node.js applications that selects the best response format based on client Accept headers

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/negotiator@1.0.x

To install, run

npx @tessl/cli install tessl/npm-negotiator@1.0.0

index.mddocs/

Negotiator

Negotiator is an HTTP content negotiation library for Node.js applications that automatically selects the most appropriate response format based on client preferences expressed in HTTP Accept headers. It supports negotiation for media types, languages, character sets, and encodings, parsing quality values and priority rankings to determine optimal matches from available options.

Package Information

  • Package Name: negotiator
  • Package Type: npm
  • Language: JavaScript (Node.js)
  • Installation: npm install negotiator

Core Imports

const Negotiator = require('negotiator');

Basic Usage

const Negotiator = require('negotiator');

// Create negotiator from request object
const negotiator = new Negotiator(request);

// Negotiate media types
const availableTypes = ['text/html', 'application/json', 'text/plain'];
const preferredType = negotiator.mediaType(availableTypes);
// Returns: 'text/html' (if client prefers HTML)

// Negotiate languages
const availableLanguages = ['en', 'es', 'fr'];
const preferredLanguage = negotiator.language(availableLanguages);
// Returns: 'en' (if client prefers English)

// Negotiate encodings
const availableEncodings = ['gzip', 'identity'];
const preferredEncoding = negotiator.encoding(availableEncodings);
// Returns: 'gzip' (if client accepts gzip)

Architecture

Negotiator is built around a single constructor class that provides:

  • Constructor-based API: Create instances from HTTP request objects containing Accept headers
  • Negotiation Methods: Methods for each HTTP Accept header type (Accept, Accept-Language, Accept-Charset, Accept-Encoding)
  • Quality Value Parsing: Automatic parsing of q-values and priority rankings according to RFC 2616
  • Backward Compatibility: Legacy method aliases for older API versions

Capabilities

Media Type Negotiation

Negotiates the best media type from the Accept header based on client preferences and available options.

/**
 * Create a Negotiator instance from a request object
 * @param {Object} request - HTTP request object with headers property
 */
function Negotiator(request);

/**
 * Returns the most preferred media type from client
 * @param {string[]} [available] - Array of available media types
 * @returns {string|undefined} Most preferred media type, '*/*' if no Accept header, or undefined if none match
 */
Negotiator.prototype.mediaType(available);

/**
 * Returns array of preferred media types ordered by client preference
 * @param {string[]} [available] - Array of available media types
 * @returns {string[]} Array of media types in preference order
 */
Negotiator.prototype.mediaTypes(available);

Usage Examples:

const negotiator = new Negotiator(request);

// Get all client preferences in order
const allTypes = negotiator.mediaTypes();
// Returns: ['text/html', 'application/json', 'text/plain']

// Get best match from available types
const available = ['application/json', 'text/plain'];
const best = negotiator.mediaType(available);
// Returns: 'application/json' (if client prefers JSON over plain text)

Language Negotiation

Negotiates the best language from the Accept-Language header based on client preferences and available options.

/**
 * Returns the most preferred language from client
 * @param {string[]} [available] - Array of available languages
 * @returns {string|undefined} Most preferred language, '*' if no Accept-Language header, or undefined if none match
 */
Negotiator.prototype.language(available);

/**
 * Returns array of preferred languages ordered by client preference
 * @param {string[]} [available] - Array of available languages
 * @returns {string[]} Array of languages in preference order
 */
Negotiator.prototype.languages(available);

Usage Examples:

const negotiator = new Negotiator(request);

// Get client language preferences
const languages = negotiator.languages();
// Returns: ['en-US', 'en', 'es'] (based on Accept-Language header)

// Find best match from available languages
const available = ['en', 'fr', 'de'];
const bestLanguage = negotiator.language(available);
// Returns: 'en' (if client prefers English)

Charset Negotiation

Negotiates the best character set from the Accept-Charset header based on client preferences and available options.

/**
 * Returns the most preferred charset from client
 * @param {string[]} [available] - Array of available charsets
 * @returns {string|undefined} Most preferred charset, '*' if no Accept-Charset header, or undefined if none match
 */
Negotiator.prototype.charset(available);

/**
 * Returns array of preferred charsets ordered by client preference
 * @param {string[]} [available] - Array of available charsets
 * @returns {string[]} Array of charsets in preference order
 */
Negotiator.prototype.charsets(available);

Usage Examples:

const negotiator = new Negotiator(request);

// Get charset preferences
const charsets = negotiator.charsets();
// Returns: ['utf-8', 'iso-8859-1'] (if no Accept-Charset, defaults to '*')

// Find best charset match
const available = ['utf-8', 'iso-8859-1', 'ascii'];
const bestCharset = negotiator.charset(available);
// Returns: 'utf-8' (if client prefers UTF-8)

Encoding Negotiation

Negotiates the best encoding from the Accept-Encoding header based on client preferences and available options. Supports preferred encoding arrays for tie-breaking.

/**
 * Returns the most preferred encoding from client
 * @param {string[]} [available] - Array of available encodings
 * @param {Object} [options] - Options object
 * @param {string[]} [options.preferred] - Preferred encodings for tie-breaking
 * @returns {string|undefined} Most preferred encoding, 'identity' if no Accept-Encoding header, or undefined if none match
 */
Negotiator.prototype.encoding(available, options);

/**
 * Returns array of preferred encodings ordered by client preference
 * @param {string[]} [available] - Array of available encodings
 * @param {Object} [options] - Options object
 * @param {string[]} [options.preferred] - Preferred encodings for tie-breaking
 * @returns {string[]} Array of encodings in preference order
 */
Negotiator.prototype.encodings(available, options);

Usage Examples:

const negotiator = new Negotiator(request);

// Get encoding preferences
const encodings = negotiator.encodings();
// Returns: ['gzip', 'deflate', 'identity'] (based on Accept-Encoding)

// Find best encoding with server preferences
const available = ['gzip', 'deflate', 'identity'];
const options = { preferred: ['gzip', 'deflate'] };
const bestEncoding = negotiator.encoding(available, options);
// Returns: 'gzip' (if client accepts and server prefers gzip)

// Identity encoding is automatically added with lowest quality if not specified
const identityIncluded = negotiator.encodings(['gzip']);
// Returns: ['gzip', 'identity'] (identity added automatically)

Backward Compatibility Methods

Legacy method names are supported for backward compatibility:

// These are aliases to the main methods
Negotiator.prototype.preferredCharset = Negotiator.prototype.charset;
Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets;
Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding;
Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings;
Negotiator.prototype.preferredLanguage = Negotiator.prototype.language;
Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages;
Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType;
Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes;

Error Handling

Single methods (.mediaType(), .language(), .charset(), .encoding()):

  • Return default values when no Accept header is present (*/*, *, *, identity respectively)
  • Return undefined when no acceptable match is found from available options

Array methods (.mediaTypes(), .languages(), .charsets(), .encodings()):

  • Return arrays with default values when no Accept header is present
  • Return arrays with acceptable matches in preference order
  • Return empty arrays when no acceptable matches are found
const negotiator = new Negotiator(request);

// No matching media type from available options
const result = negotiator.mediaType(['application/xml']);
// Returns: undefined (if client doesn't accept XML)

// No Accept header present - returns default
const defaultType = negotiator.mediaType();
// Returns: '*/*' (RFC 2616 default)

// Array method with no header - returns default array
const allTypes = negotiator.mediaTypes();
// Returns: ['*/*'] (default array when no Accept header)

Quality Values and RFC 2616 Compliance

Negotiator follows RFC 2616 specifications for HTTP content negotiation:

  • Quality values (q-values) are parsed and respected (e.g., text/html;q=0.8)
  • Missing headers are treated according to RFC defaults (e.g., * for charset, */* for media types)
  • Specificity rules are applied (more specific matches take precedence)
  • Wildcard matching is supported (*/*, text/*, *)

Types

/**
 * HTTP request object expected by Negotiator constructor
 */
interface Request {
  headers: {
    accept?: string;
    'accept-language'?: string;
    'accept-charset'?: string;
    'accept-encoding'?: string;
  };
}

/**
 * Options object for encoding negotiation
 */
interface EncodingOptions {
  preferred?: string[];
}