@prasadaabhishek/linkheader
v0.1.0
Published
Zero-dependency RFC 8288 Link HTTP header parser and builder for Node.js
Maintainers
Readme
linkheader
Zero-dependency RFC 8288 Link HTTP header parser and builder for Node.js.
Why linkheader?
Node.js developers building HTTP API clients, pagination handlers, and web
scrapers need to parse RFC 8288 Link HTTP header values — pagination
(rel="next", rel="prev"), web-linking (rel="canonical",
rel="alternate"), Memento (rel="memento"). The jshttp ecosystem
(content-type,
content-disposition,
accepts, fresh,
range-parser) provides every other
HTTP header primitive but has no link-header package. Existing
alternatives on npm depend on ramda (~1000 LOC functional library) or
xtend, are unmaintained, or only support half the surface (parse but not
build, or build but not parse).
linkheader closes the gap with a single, well-tested, zero-dependency
library covering parse, build, and relation lookup end-to-end.
Quick start
const { parseLinkHeader, findLinkRelation, buildLinkHeader } = require('linkheader');
const header = '<https://api.example.com/users?page=2>; rel="next", ' +
'<https://api.example.com/users?page=1>; rel="prev", ' +
'<https://api.example.com/users/123>; rel="alternate"; type="text/html"';
const links = parseLinkHeader(header);
const next = findLinkRelation(header, 'next');
const serialized = buildLinkHeader(links);API
parseLinkHeader(header) => LinkHeaderEntry[]
Parse an RFC 8288 Link header value (without the Link: prefix) into an
array of entries.
| Entry field | Type | Description |
|-------------|----------|----------------------------------------------------------|
| uri | string | The URI (absolute or relative), stripped of < >. |
| rel | string[] | Relation types, lowercased and space-split. |
| params | Record<string, string> | Other parameters (title, type, hreflang, media, etc.). title* is stored under titleStar (already percent-decoded). |
Returns [] for empty / null / undefined input.
findLinkRelation(header, rel, options?) => string | string[] | null
Look up URIs by relation type. Case-insensitive.
- Without
{ all: true }: returns the first matching URI as a string, ornullif not found. - With
{ all: true }: returns an array of matching URIs, ornullif no matches.
findLinkRelation(header, 'next'); // 'https://...'
findLinkRelation(header, 'alternate', { all: true }); // ['https://...', ...]buildLinkHeader(links) => string
Serialize an array of LinkHeaderEntry objects back into a header value.
The output is round-trippable through parseLinkHeader (modulo
normalization: rel values are lowercased).
titleStar(and any key whose name ends inStar) is emitted as the RFC 5987 extended formtitle*=UTF-8''<percent-encoded>.- All other parameter values are emitted as quoted strings; double-quotes and backslashes are escaped per the RFC.
Install
npm install @prasadaabhishek/linkheaderCompatibility
- Node.js ≥ 14 (CommonJS and ESM both work via
package.jsonexports). - Zero runtime dependencies.
⚡ Performance & Benchmarks
Run node benchmarks/benchmark.js to reproduce the local benchmark. The
latest results (Node v22.23.1, Linux x64) live in
benchmarks/results.json. Methodology: 50
iterations per workload, mean / p50 / p95 / stddev / min / max via
process.hrtime.bigint().
Limitations
- Does not implement full RFC 8288 Web Linking extension relation types beyond parsing/serialization (no relation-type registry, no IANA lookups).
- Does not implement HTTP client/server logic.
- Does not implement URI template expansion (RFC 6570).
- Does not implement Memento-specific headers (
Memento-Datetime,Timegate-Accept-Datetime). - The
*Starkeying fortitle*is a deliberate namespace separation so that the raw (percent-encoded) and decoded forms are not confused. - The library emits the
title*=UTF-8''...form fortitleStarkeys unconditionally. Plaintitleis emitted only as a quoted string. No automatic selection between the two — callers must choose.
License
MIT — see LICENSE.
