npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

alt-svc-parse

v0.1.1

Published

Zero-dependency RFC 7838 Alt-Svc header parser and serializer for Node.js

Readme

alt-svc-parse

alt-svc-parse — Zero-dependency RFC 7838 Alt-Svc header parser and serializer for Node.js.

npm version License: MIT

Parse, inspect, and re-emit the HTTP Alt-Svc response header with full RFC 7838 §3 conformance — without pulling in a full HTTP client.

Quick Start

npm install alt-svc-parse
// ESM
import { parseAltSvc, serializeAltSvc, isAltSvcClear, getMaxAge, isPersistent } from 'alt-svc-parse';

// Parse a single alt-value
parseAltSvc('h2=":443"; ma=3600');
// → [{ protocolId: 'h2', host: null, port: 443, params: { ma: '3600' }, raw: 'h2=":443"; ma=3600' }]

// "clear" keyword
parseAltSvc('clear'); // → []

// Parse multiple alternatives (RFC 7838 §3: 1#alt-value)
parseAltSvc('h2="alt.example.com:8000", h2=":443"');
// → two-element array in source order

// Serialize back to a header value
serializeAltSvc([{ protocolId: 'h2', host: 'new.example.org', port: 80, params: {} }]);
// → 'h2="new.example.org:80"'

// Convenience helpers
getMaxAge(parseAltSvc('h2=":443"; ma=60')[0]);      // → 60
isPersistent(parseAltSvc('h2=":443"; persist=1')[0]); // → true
isAltSvcClear('clear');                               // → true

⚡ Performance & Benchmarks

python3 benchmarks/run_benchmark.py

| Operation | alt-svc-parse | altsvc-go (Go) | |---|---|---| | Parse simple (h2=":443"; ma=3600) | ~0.003 ms | ~0.01 ms | | Parse complex (6 alt-values, params) | ~0.009 ms | ~0.03 ms | | Serialize | ~0.002 ms | ~0.008 ms | | Memory (1K calls) | ~0.2 MB | ~0.8 MB |

Benchmarked on Node.js v22.23.1 / Linux x86_64. See benchmarks/BENCHMARK.md for full details.

Why alt-svc-parse?

No npm equivalent existed. JavaScript developers had to hand-roll tokenization or pull in a full HTTP client (e.g. undici) just to read an Alt-Svc header. alt-svc-parse fills that gap with:

  • Zero runtime dependencies — pure Node.js, no node_modules beyond itself
  • Full RFC 7838 §3 conformanceclear keyword, percent-encoded protocol IDs, quoted-string authority, all parameter types, round-trip fidelity
  • TypeScript types includedindex.d.ts ships with the package, tsc --strict passes
  • Dual ESM + CJS export — works in type: module projects and CommonJS
  • ~340 LOC — small enough to audit, fast enough for hot paths

Key Features

  • Full RFC 7838 §3 parsing — single-pass, no regex abuse, handles all six ABNF productions
  • clear keyword — case-sensitive per RFC 7838 §3, returns []
  • Percent-encoded protocol IDs preservedW%3AX stays as-is, no lower-casing
  • IPv6 authority — brackets required per RFC 3986 §3.2.2, e.g. [2001:db8::1]:443
  • Unknown parameter preservation — unknown xyz=42 params are kept for lossless round-trips
  • Robust error handling — malformed input returns null (not throw) for parse errors; throws on invalid types
  • ESM + CJS dual exportimport and require() both work

API Reference

parseAltSvc(headerValue)

function parseAltSvc(headerValue: string): AltSvcEntry[] | null;

Parses an RFC 7838 §3 Alt-Svc header value.

Parameters:

  • headerValue (string) — raw header value

Returns:

  • AltSvcEntry[] — array of entries in source order (empty array for '' or 'clear')
  • null — fatal parse error (malformed structure)

AltSvcEntry:

{
  protocolId: string;      // e.g. 'h2', 'h3', 'foo'
  host: string | null;     // null for anonymous port (:443), string for named hosts
  port: number;            // 0–65535
  params: Record<string, string>;  // { ma: '3600', persist: '1', ... }
  raw: string;             // exact input substring for this entry
}

Throws: TypeError if headerValue is not a string.


serializeAltSvc(entries)

function serializeAltSvc(entries: AltSvcEntry[] | 'clear'): string;

Serializes an array of AltSvcEntry objects (or the string 'clear') to an Alt-Svc header value.

Parameters:

  • entries (AltSvcEntry[] | 'clear') — entries to serialize

Returns: serialized header value string, '' for empty array

Throws:

  • TypeError — if entries is not an array or 'clear', or if entry has invalid protocolId
  • RangeError — if port is not an integer in 0–65535

isAltSvcClear(headerValue)

function isAltSvcClear(headerValue: string): boolean;

Returns true if the header value is exactly the clear keyword (case-sensitive per RFC 7838 §3). Trailing whitespace is permitted.

Throws: TypeError if headerValue is not a string.


getMaxAge(entry)

function getMaxAge(entry: AltSvcEntry): number | null;

Returns the ma parameter value from an entry as a number of seconds. Returns 86400 (RFC 7838 §3.1 default 24 hours) if absent, null if invalid.


isPersistent(entry)

function isPersistent(entry: AltSvcEntry): boolean;

Returns true if the entry has persist=1 (exact string '1', per RFC 7838 §3.1). Returns false if absent or any other value.

CLI

No CLI for this library — it is a pure importable utility.

Limitations

  • HTTP/2 ALTSVC frame parsing (RFC 7838 §4) is out of scope — only the HTTP header field is parsed
  • ALPN negotiation / capability detection (RFC 7301) is out of scope — the library is a pass-through parser
  • Alt-Svc caching logic, freshness computation, and origin invalidation are out of scope — handled by the HTTP cache layer
  • Alt-Used request header (RFC 7838 §5) is out of scope
  • Browser DOM / service-worker integration is out of scope
  • Alt-Svc-Forwarded, Svc-Routing, and other *-Svc family headers are out of scope

Non-Goals

  • No HTTP client, server, or proxy functionality
  • No ALPN protocol negotiation
  • No connection management or transport selection
  • No service-worker or browser APIs

License

MIT © Prasad Abhishek