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

@arnaude/source-tag

v0.4.0

Published

Zero-touch outbound service-identity headers for Node HTTP clients.

Downloads

169

Readme

IMP

Works Reliably

Node services started with

node -r dotenv/config -r source-tag ...

Common HTTP clients using Node transports:

http https request axios node-fetch built-in fetch most REST SDKs built on these

Local, staging, prod, Docker, PM2, npm scripts, as long as preload is present in the actual process

Does Not Automatically Work

Child processes unless they also preload source-tag Calls made by another container, proxy, sidecar, gateway, or service mesh Non-HTTP protocols Native/custom networking code Libraries that bypass Node HTTP/HTTPS/fetch/http2/undici internals Services not started through the edited package.json script Existing explicit X-Source-Service header, because source-tag preserves caller-provided values Must Verify Per Service

Start service Hit outbound echo endpoint Confirm echo receives: X-Source-Service:

Also include a tiny checklist:

npm i source-tag SERVICE_NAME=my-service node -r dotenv/config -r source-tag dist/server.js

Then test with echo.

source-tag

Zero-touch outbound service-identity headers for supported Node.js HTTP clients.

Preload once, and outbound HTTP calls made through supported Node.js transports will automatically carry a service identity header:

X-Source-Service: <service-name>

No per-request instrumentation is required in application code.


Quick Start

SERVICE_NAME=my-service node -r source-tag server.js

For TypeScript services using ts-node:

SERVICE_NAME=my-service ts-node -r source-tag src/index.ts

If your service loads environment variables from a .env file, preload dotenv before source-tag so SERVICE_NAME is available when source-tag initializes:

node -r dotenv/config -r source-tag server.js

For a local folder preload:

node -r dotenv/config -r ./source-tag server.js

Compatibility

Minimum supported version:

  • Node.js 14

Actively tested in CI against:

  • Node.js 14
  • Node.js 16
  • Node.js 18
  • Node.js 20
  • Node.js 22

Features such as globalThis.fetch are only patched when available in the current runtime.

Newer Node.js releases may work but are not guaranteed until added to the compatibility test matrix.


What It Does

source-tag patches supported outbound HTTP transports inside the current Node.js process.

When an outbound request is made, it adds this header unless the caller has already set it:

X-Source-Service: <service-name>

If the caller already set the source header, that value is preserved.

The check is case-insensitive, so these are treated as the same header:

X-Source-Service
x-source-service

Service Name Resolution

source-tag resolves the service name from the first value it finds, in this order:

| Priority | Source | | -------- | --------------------------------------------------------------- | | 1 | SERVICE_NAME environment variable | | 2 | SOURCE_SERVICE environment variable | | 3 | npm_package_name environment variable | | 4 | name field in package.json at the current working directory |

If none of these resolve to a value, source-tag logs a warning and exits without patching anything.

In strict mode, a missing service name is treated as a startup failure.


Coverage

source-tag patches supported outbound HTTP transports at the Node.js runtime level.

| Transport | Covered | | ------------------------------------------------------------ | ----------------------------------------------- | | http.request, http.get | Yes | | https.request, https.get | Yes | | Axios | Yes, via Node HTTP/HTTPS | | Got | Yes, via Node HTTP/HTTPS | | node-fetch v2 | Yes, via Node HTTP/HTTPS | | SuperAgent | Yes, via Node HTTP/HTTPS | | Needle | Yes, via Node HTTP/HTTPS | | Request | Yes, via Node HTTP/HTTPS | | globalThis.fetch | Yes, when available | | HTTP/2 sessions via http2.connect | Yes | | Undici request, stream, pipeline, connect, upgrade | Yes, if Undici is installed | | Undici dispatcher/client paths | Best effort via Dispatcher.prototype.dispatch |


Known Limitations

source-tag covers supported Node.js HTTP transports in the current process. It does not guarantee coverage for every possible outbound network call.

It does not cover:

  • Child processes unless they also preload source-tag
  • Non-HTTP protocols
  • Custom native networking code
  • Traffic sent by another service, sidecar, proxy, or container
  • Libraries that completely bypass Node's HTTP, HTTPS, Fetch, HTTP/2, and Undici paths

The service name and header name are resolved once at preload time.

If the module is loaded multiple times with different configurations, the first active configuration wins.

For HTTP/2, header names are sent in lowercase as required by the protocol:

x-source-service: my-service

Configuration

All configuration is provided through environment variables.

| Variable | Required | Default | Purpose | | -------------------- | ----------- | -------------------------- | ---------------------------------------------- | | SERVICE_NAME | Recommended | Falls back to package name | Value placed in the source header | | SOURCE_SERVICE | No | None | Alternative service-name variable | | SOURCE_HEADER | No | X-Source-Service | Override the header name | | DISABLE_SOURCE_TAG | No | Unset | Disable source-tag entirely | | SOURCE_TAG_STRICT | No | Unset | Fail startup on critical initialization errors | | SOURCE_TAG_DISABLE_HTTP | No | Unset | Disable http and https patching | | SOURCE_TAG_DISABLE_FETCH | No | Unset | Disable globalThis.fetch patching | | SOURCE_TAG_DISABLE_HTTP2 | No | Unset | Disable HTTP/2 patching | | SOURCE_TAG_DISABLE_UNDICI | No | Unset | Disable all Undici patching |


Transport Opt-Outs

Each supported transport can be disabled independently without changing application code:

SOURCE_TAG_DISABLE_HTTP=1
SOURCE_TAG_DISABLE_FETCH=1
SOURCE_TAG_DISABLE_HTTP2=1
SOURCE_TAG_DISABLE_UNDICI=1

For an initial canary with only HTTP/HTTPS patching enabled:

SERVICE_NAME=my-service \
SOURCE_TAG_DISABLE_FETCH=1 \
SOURCE_TAG_DISABLE_HTTP2=1 \
SOURCE_TAG_DISABLE_UNDICI=1 \
node -r source-tag server.js

This keeps http.request, http.get, https.request, and https.get enabled, while leaving Fetch, HTTP/2, and Undici unpatched.


Custom Header Name

SERVICE_NAME=payments-service
SOURCE_HEADER=X-Caller-Service
node -r source-tag server.js

Outbound requests will carry:

X-Caller-Service: payments-service

For HTTP/2:

x-caller-service: payments-service

Emergency Disable

If source-tag causes an issue in any environment, disable it without changing application code:

DISABLE_SOURCE_TAG=1 node -r source-tag server.js

When disabled, source-tag does not patch any transports and does not add headers.

For canary rollback, remove any transport-specific opt-outs only after clearing the incident; DISABLE_SOURCE_TAG=1 is the full emergency stop.


Strict Mode

By default, source-tag is fail-open.

If initialization fails, source-tag logs the problem and allows the host application to continue running.

For environments where the source header is mandatory:

SOURCE_TAG_STRICT=1 SERVICE_NAME=my-service node -r source-tag server.js

In strict mode, startup fails if:

  • No service name can be resolved
  • The configured header name is invalid
  • The resolved service name is not a valid HTTP header value
  • A critical transport patch fails

This makes configuration problems visible during deployment instead of silently allowing services to run without source headers.


Header Safety

source-tag validates the configured header name before using it.

Invalid SOURCE_HEADER values fall back to:

X-Source-Service

In strict mode, an invalid header name causes startup failure.

The resolved service name is trimmed before use.

CR, LF, and NUL characters are removed to prevent HTTP header injection.


Mutation Safety

source-tag clones request options and nested header containers before adding the source header.

It avoids mutating caller-provided request configuration, including:

  • Plain objects
  • Map
  • Fetch Headers
  • Array-of-tuples headers
  • Flat header arrays

This is important for applications that reuse request configurations for retries, telemetry, logging, caching, or multiple outbound requests.


Startup Log

On successful initialization, source-tag writes a structured JSON log line to stdout.

Example:

{
  "level": "info",
  "time": "2026-06-04T10:23:45.123Z",
  "module": "source-tag",
  "msg": "active",
  "service": "my-service",
  "header": "X-Source-Service",
  "strict": false,
  "transportOptOuts": {
    "SOURCE_TAG_DISABLE_HTTP": false,
    "SOURCE_TAG_DISABLE_FETCH": false,
    "SOURCE_TAG_DISABLE_HTTP2": false,
    "SOURCE_TAG_DISABLE_UNDICI": false
  },
  "patched": ["http", "https", "fetch"],
  "alreadyPatched": [],
  "skipped": ["undici"],
  "failed": []
}

Warnings and errors are written to stderr using the same JSON-line format.

Startup Log Fields

| Field | Meaning | | ---------------- | -------------------------------------------- | | patched | Transport patched during this initialization | | alreadyPatched | Transport was already patched | | skipped | Transport unavailable or not applicable | | failed | Patch failed | | transportOptOuts | Per-transport disable flags active at startup |


Package Usage

This package is a preload side-effect module.

Use it with Node's -r flag:

node -r source-tag server.js

or:

node -r ./source-tag server.js

source-tag is not intended to expose a public JavaScript or TypeScript API.


Operational Notes

  • DISABLE_SOURCE_TAG=1 disables the module completely
  • SOURCE_TAG_DISABLE_HTTP=1 disables http and https patching
  • SOURCE_TAG_DISABLE_FETCH=1 disables globalThis.fetch patching
  • SOURCE_TAG_DISABLE_HTTP2=1 disables HTTP/2 patching
  • SOURCE_TAG_DISABLE_UNDICI=1 disables all Undici patching
  • SOURCE_TAG_STRICT=1 is recommended when source headers are mandatory
  • Patches are idempotent
  • Loading the module multiple times with the same configuration does not patch again
  • Loading the module multiple times with different configurations keeps the first active configuration
  • Undici support is optional and only enabled when Undici is installed
  • globalThis.fetch is only patched when available
  • HTTP/2 header names are automatically lowercased
  • The module is process-local; other processes must preload source-tag separately

Local Development Example

For a service named spartacus:

.env

SERVICE_NAME=spartacus
NODE_OPTIONS=-r ./source-tag

If the service uses dotenv:

node -r dotenv/config \
     -r ./source-tag \
     -r tsconfig-paths/register \
     -r ts-node/register \
     index.ts

Initialization order:

  1. dotenv/config loads environment variables
  2. source-tag resolves configuration and patches transports
  3. tsconfig-paths/register enables TypeScript path aliases
  4. ts-node/register enables TypeScript execution
  5. index.ts starts the application

Testing

source-tag is actively tested in CI across supported Node.js versions.

Current automated coverage includes:

  • http.request
  • http.get
  • https.request
  • https.get
  • globalThis.fetch
  • HTTP/2
  • Existing-header preservation
  • Case-insensitive header detection
  • Strict mode
  • Disable mode
  • Service-name resolution
  • Idempotent initialization
  • Mutation safety for supported header formats

Before broad production adoption, verify source-tag with the transports and request patterns used by your own services.