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

sec-fetch-parse

v0.1.0

Published

Zero-dependency parser for HTTP Sec-Fetch-* request headers

Readme

sec-fetch-parse

Zero-dependency Node.js parser for HTTP Sec-Fetch- request headers.*

Implements W3C Fetch Metadata (SecFetchDest, SecFetchMode, SecFetchSite, SecFetchUser). 162 tests, TypeScript definitions, MIT licensed.

const {
  parseSecFetchDest,
  parseSecFetchMode,
  parseSecFetchSite,
  parseSecFetchUser,
  InvalidSecFetchHeader,
} = require('sec-fetch-parse');

const dest = parseSecFetchDest('image');           // → 'image'
const mode = parseSecFetchMode('cors');            // → 'cors'
const site = parseSecFetchSite('same-origin');     // → 'same-origin'
const user = parseSecFetchUser('?1');              // → true

Why?

The fetch-metadata npm package enforces Fetch Metadata policy by rejecting non-conforming requests, but it does not expose a typed parser for individual Sec-Fetch-* header values. Every server that wants to log, inspect, or conditionally route based on fetch metadata must hand-roll string splitting. No zero-dependency npm package parses these four headers into typed objects — until now.

sec-fetch-parse fills that gap with a small, focused, zero-dependency parser that follows the W3C Fetch Metadata spec exactly.

Quick start

npm install sec-fetch-parse
const {
  parseSecFetchDest,
  parseSecFetchMode,
  parseSecFetchSite,
  parseSecFetchUser,
  InvalidSecFetchHeader,
} = require('sec-fetch-parse');

// Basic parsing — every W3C enum value parses back to itself.
parseSecFetchDest('document');           // → 'document'
parseSecFetchMode('navigate');           // → 'navigate'
parseSecFetchSite('cross-site');         // → 'cross-site'
parseSecFetchUser('?1');                 // → true (the only valid true value)

// Sec-Fetch-User: ?1 → true; absent/null/undefined/empty → false.
parseSecFetchUser(undefined);            // → false (absent header)
parseSecFetchUser('');                   // → false
parseSecFetchUser('?0');                 // → false (?1 is the only valid true)

// Unknown / future values passthrough for forward-compatibility (per W3C spec).
parseSecFetchDest('custom-value');       // → 'custom-value'

// Invalid types throw InvalidSecFetchHeader.
try {
  parseSecFetchDest(42);
} catch (err) {
  if (err instanceof InvalidSecFetchHeader) {
    // handle
  }
}

Real-world middleware example

const express = require('express');
const {
  parseSecFetchDest,
  parseSecFetchMode,
  parseSecFetchSite,
  parseSecFetchUser,
} = require('sec-fetch-parse');

const app = express();

app.use((req, res, next) => {
  const dest   = parseSecFetchDest(req.headers['sec-fetch-dest']);
  const mode   = parseSecFetchMode(req.headers['sec-fetch-mode']);
  const site   = parseSecFetchSite(req.headers['sec-fetch-site']);
  const isUser = parseSecFetchUser(req.headers['sec-fetch-user']);

  // OWASP CSRF defense: cross-origin iframe embeds of our pages are forbidden.
  if (dest === 'iframe' && site === 'cross-site') {
    return res.status(403).send('Embedding not allowed');
  }

  // Log structured fetch metadata for audit trails.
  console.log({ dest, mode, site, isUser });
  next();
});

API

parseSecFetchDest(value: unknown): string

Parse a Sec-Fetch-Dest header value.

  • Returns the value as-is (passthrough semantics per W3C forward-compatibility clause).
  • Throws InvalidSecFetchHeader if value is not a string.

W3C enum (16 known values): audio, audiowave, video, image, font, script, style, track, embed, object, document, serviceworker, sharedworker, worker, manifest, xslt.

parseSecFetchMode(value: unknown): string

Parse a Sec-Fetch-Mode header value.

  • Returns the value as-is (passthrough).
  • Throws InvalidSecFetchHeader if value is not a string.

W3C enum (7 known values): navigate, same-origin, no-site (deprecated), no-cors, cors, websocket, preflight.

parseSecFetchSite(value: unknown): string

Parse a Sec-Fetch-Site header value.

  • Returns the value as-is (passthrough).
  • Throws InvalidSecFetchHeader if value is not a string.

W3C enum (4 known values): cross-site, same-origin, same-site, none.

parseSecFetchUser(value: unknown): boolean

Parse a Sec-Fetch-User header value.

  • Returns true only for ?1 (the only valid value per W3C spec).
  • Returns false for undefined, null, or empty string (absent header semantics).
  • Throws InvalidSecFetchHeader for any other type.

InvalidSecFetchHeader

Error class thrown when input type is invalid. Extends Error; err.name === 'InvalidSecFetchHeader'. Use instanceof to distinguish from generic Errors.

TypeScript

index.d.ts is included. No need for @types/sec-fetch-parse.

import {
  parseSecFetchDest,
  parseSecFetchMode,
  parseSecFetchSite,
  parseSecFetchUser,
  InvalidSecFetchHeader,
} from 'sec-fetch-parse';

const dest: string = parseSecFetchDest('document');
const isUser: boolean = parseSecFetchUser('?1');

tsc --noEmit index.d.ts passes cleanly.

Testing

npm test

Runs the full test suite via node --test tests/*.test.js. 162 tests across 5 test files, all passing. Each of the 35 spec acceptance criteria has at least one dedicated test.

Out of scope (limitations / non-goals)

  • No policy enforcement. If you need a middleware that rejects non-conforming requests, use fetch-metadata. This library only parses.
  • Sec-Fetch-Digest is NOT supported — it is a response header (digest integrity), not a request header. Separate concern.
  • No browser-side header construction. This is a server-side parser.
  • No network I/O. This library is pure logic, no HTTP client/server.
  • No header normalization. Whitespace and case are significant; the parser does not trim. W3C defines values as lowercase ASCII; non-conforming values passthrough verbatim.

Evidence of need

  1. sec-fetch-parse name is available on npm — verified 2026-08-05, npm view sec-fetch-parse returns 404.
  2. fetch-metadata (jperasmus, MIT) enforces policy but does not parse. Multiple GitHub issues request parsed access; the maintainer's stated position is that the package is "middleware for enforcing Fetch metadata request header checking," not a parser.
  3. W3C Fetch Metadata spec defines precise grammar for all four headers; this library follows it.
  4. OWASP lists Fetch Metadata request header checking as a Tier 1 server-side CSRF defense.

References

License

MIT — see LICENSE.