Detect telemetry in your JS/TS dependencies and disable it in one command.
The name applies to the CLI, too: no-telemetry collects no telemetry, has zero production dependencies, and makes no runtime network requests.

DO_NOT_TRACK convention.Run these commands from the directory containing your package.json:
npx no-telemetry init -y # add missing opt-out variables to .env
npx no-telemetry doctor # show telemetry status
npx no-telemetry check # same report; exit 1 if anything is still enabled
Want to inspect the change first?
npx no-telemetry init --dry-run
Agents and CI can use structured output:
npx no-telemetry init -y --json
npx no-telemetry check --json=compact # one-line JSON for pipes
npx no-telemetry list --json # registry coverage; no project needed
npx no-telemetry why next --json # env variable and docs for one tool
After init, doctor prints a per-tool status table:
Library Status Variable
────────────────────────────────────────────
Next.js ✓ disabled NEXT_TELEMETRY_DISABLED=1
Turborepo ✓ disabled TURBO_TELEMETRY_DISABLED=1
Prisma ✓ disabled CHECKPOINT_DISABLE=1
3 of 3 applicable libraries have telemetry disabled.
doctor always exits 0. Use check when enabled telemetry should fail a build.
The bundled registry currently knows about 43 tools: 34 documented environment-variable opt-outs, 2 opt-in checks, and 7 config-only tools that are detected and reported without being changed.
That includes Next.js, Prisma, Vercel CLI, Turborepo, Storybook, Expo, Wrangler, Supabase CLI, GitHub CLI, Claude Code, and more.
npx no-telemetry list # show every registry entry
npx no-telemetry why turbo # show Turbo's variables, notes, and official docs
Is your tool missing? Adding a registry entry is a small, data-only contribution.
Unlike manually grepping documentation or maintaining a broad list such as toptout, no-telemetry detects the tools in the current project, applies their documented dotenv opt-outs, and can enforce the result in CI.
dependencies and devDependencies from the current directory's package.json..env or another target you choose..env.local, and .env, then reports whether telemetry is disabled.The CLI is deliberately narrow:
npx may download the package itself when it is not already cached.)KEY= placeholders in place and keeps new variables in one marker-delimited block..env.package.json.DO_NOT_TRACK=1 alongside any tool-specific variables.init is idempotent.no-telemetry scans one package.json in the current directory. It does not currently scan workspaces or transitive dependencies.
The registry focuses on environment-variable opt-outs. Tools that require config files or saved CLI state are reported as unsupported and left untouched.
doctor and check resolve values in this precedence order: process environment, .env.local, then .env.
Pin the version so your policy does not change unexpectedly:
- name: Telemetry opt-out check
run: npx --yes no-telemetry@0.2.0 check --json=compact
To apply opt-outs after scaffolding and then verify them:
- run: npx --yes no-telemetry@0.2.0 init -y
- run: npx --yes no-telemetry@0.2.0 check --json=compact
The first --yes accepts the npx install. The -y after init accepts the file write.
initReads package.json, matches direct dependencies against the built-in registry, and adds missing opt-out variables to the write target. The default target is .env.
| Flag | Meaning |
|---|---|
--yes / -y | Skip confirmation (required when non-TTY or CI=true) |
--dry-run | Show what would be written; do not write |
--json | Machine-readable report (version: 1) |
--target <path> | Any env-file path, or stdout (default: .env) |
--example | Shorthand for --target .env.example (commit-safe opt-out template) |
init does not accept --only, --ignore, or --all; those flags belong to doctor and check.
stdout)KEY= placeholders in placeDO_NOT_TRACK=1stdout mode, writes pure KEY=VALUE lines to stdout and diagnostics to stderr--target stdout --json, keeps dotenv lines on stdout and sends the JSON report to stderr--example / .env.example like any other dotenv target; generated values contain no secretsdoctorPrints a per-library table and always exits 0. Installed libraries determine the summary. The human-readable table hides not found rows unless you pass --all.
| Flag | Meaning |
|---|---|
--json | Full machine-readable report |
--only <filter> | installed or failing |
--ignore <value> | Omit by id, display name, or package; repeatable |
--all | Include not-found rows in the human table |
doctor and check do not accept --yes, --dry-run, or --target.
--only filters libraries[] in JSON; summary retains the full post---ignore policy counts.
checkProduces the same output as doctor, but exits 1 if any installed, applicable library still has telemetry enabled after --ignore.
npx no-telemetry check
listDumps the full registry without reading package.json. Use it to discover coverage or feed registry data to another tool.
npx no-telemetry list
npx no-telemetry list --json
why <id>Explains one registry entry: environment variables, official docs, notes, and alternate satisfaction signals.
npx no-telemetry why next
npx no-telemetry why turbo --json
| Flag | Meaning |
|---|---|
--json | Pretty-printed JSON report (version: 1) |
--json=compact | One-line JSON for pipes |
--quiet / -q | Suppress human diagnostics; with --json, also selects compact output |
--version / -V | Print version |
--help / -h | Show help |
| Environment variable | Effect |
|---|---|
NO_COLOR | Disable ANSI colors when set to any non-empty value |
FORCE_COLOR | Force colors outside a TTY (0 disables them) |
| Code | Meaning |
|---|---|
0 | Success; doctor always, check when policy passes, or init completes |
1 | Policy failure; check found enabled telemetry, or interactive init was aborted |
2 | Tool or usage error; bad flags, missing package.json, or unconfirmed non-TTY init |
Library definitions live in src/registry.ts, the single source of truth. Each has a stable id such as next, prisma, or vercel for --ignore, why, and JSON output. Every environment variable is curated against official documentation.
Some tools honor a proprietary opt-out or DO_NOT_TRACK (for example, Turbo, Railway, and Supabase). Alternate signals use OR semantics by default. Entries with alternatePolicy: "fallback" use alternates only when the primary key is unset; this models tools such as GitHub CLI, where GH_TELEMETRY takes precedence. init still writes the primary tool-specific key plus DO_NOT_TRACK=1.
Registry entries are a discriminated union:
kind | Meaning |
|---|---|
opt-out | Telemetry is on by default; set env to disable it |
opt-in | Telemetry is off by default; enableWhen values mean it is on |
unsupported | No environment-variable opt-out; config or CLI action is required |
opt-out bindings may include accepts for multiple accepted values or non-empty semantics. Entries can also include alsoSatisfiedBy and alternatePolicy for additional signals.
The stable API is ESM-only and supports Node.js 18+:
import { scan, planInit, applyInit, failsCheck, buildReport, REGISTRY } from "no-telemetry";
const cwd = process.cwd();
const results = scan(cwd);
const failing = results.filter(failsCheck);
const report = buildReport(cwd, results);
| Export | Role |
|---|---|
scan / evaluate | Detect dependencies and evaluate status |
planInit / applyInit | Plan and apply idempotent dotenv writes |
failsCheck | Apply the check policy |
buildReport / buildErrorReport | Build the JSON DTO (version: 1) |
REGISTRY | Read the curated library data |
filterResults | Apply presentation filters |
LibraryResult.status uses machine-stable tokens: disabled, enabled, not_applicable, not_found, and unsupported. The CLI maps these to human labels such as ✓ disabled and - n/a.
Target-specific plans must be applied to the same target:
const target = ".env.local";
const plan = planInit(cwd, { target });
applyInit(cwd, plan, { target });
scan(cwd, process.env, { envFiles: [".env", ".env.local"] });
The easiest way to expand coverage is to add a typed entry to src/registry.ts:
Special matching or precedence rules should include a focused test. Config-only tools are welcome as unsupported entries so doctor can still surface them without changing user files.
See CONTRIBUTING.md for the full registry schema, development workflow, and pull request checklist.
pnpm install
pnpm run check
pnpm test
pnpm run build
The development toolchain runs on Node.js 22. The packed CLI and programmatic API are smoke-tested on Node.js 18, 20, and 22:
mkdir -p artifacts
pnpm pack --pack-destination artifacts
TARBALL=$(find artifacts -name '*.tgz' -type f -print -quit)
pnpm run test:package "$TARBALL" --tsc node_modules/.bin/tsc
Zero production dependencies. Runtime support: Node.js 18+.
15 commits
TypeScript
73.7%
JavaScript
26.3%
Detect telemetry in your JS/TS dependencies and disable it in one command.
The name applies to the CLI, too: no-telemetry collects no telemetry, has zero production dependencies, and makes no runtime network requests.

DO_NOT_TRACK convention.Run these commands from the directory containing your package.json:
npx no-telemetry init -y # add missing opt-out variables to .env
npx no-telemetry doctor # show telemetry status
npx no-telemetry check # same report; exit 1 if anything is still enabled
Want to inspect the change first?
npx no-telemetry init --dry-run
Agents and CI can use structured output:
npx no-telemetry init -y --json
npx no-telemetry check --json=compact # one-line JSON for pipes
npx no-telemetry list --json # registry coverage; no project needed
npx no-telemetry why next --json # env variable and docs for one tool
After init, doctor prints a per-tool status table:
Library Status Variable
────────────────────────────────────────────
Next.js ✓ disabled NEXT_TELEMETRY_DISABLED=1
Turborepo ✓ disabled TURBO_TELEMETRY_DISABLED=1
Prisma ✓ disabled CHECKPOINT_DISABLE=1
3 of 3 applicable libraries have telemetry disabled.
doctor always exits 0. Use check when enabled telemetry should fail a build.
The bundled registry currently knows about 43 tools: 34 documented environment-variable opt-outs, 2 opt-in checks, and 7 config-only tools that are detected and reported without being changed.
That includes Next.js, Prisma, Vercel CLI, Turborepo, Storybook, Expo, Wrangler, Supabase CLI, GitHub CLI, Claude Code, and more.
npx no-telemetry list # show every registry entry
npx no-telemetry why turbo # show Turbo's variables, notes, and official docs
Is your tool missing? Adding a registry entry is a small, data-only contribution.
Unlike manually grepping documentation or maintaining a broad list such as toptout, no-telemetry detects the tools in the current project, applies their documented dotenv opt-outs, and can enforce the result in CI.
dependencies and devDependencies from the current directory's package.json..env or another target you choose..env.local, and .env, then reports whether telemetry is disabled.The CLI is deliberately narrow:
npx may download the package itself when it is not already cached.)KEY= placeholders in place and keeps new variables in one marker-delimited block..env.package.json.DO_NOT_TRACK=1 alongside any tool-specific variables.init is idempotent.no-telemetry scans one package.json in the current directory. It does not currently scan workspaces or transitive dependencies.
The registry focuses on environment-variable opt-outs. Tools that require config files or saved CLI state are reported as unsupported and left untouched.
doctor and check resolve values in this precedence order: process environment, .env.local, then .env.
Pin the version so your policy does not change unexpectedly:
- name: Telemetry opt-out check
run: npx --yes no-telemetry@0.2.0 check --json=compact
To apply opt-outs after scaffolding and then verify them:
- run: npx --yes no-telemetry@0.2.0 init -y
- run: npx --yes no-telemetry@0.2.0 check --json=compact
The first --yes accepts the npx install. The -y after init accepts the file write.
initReads package.json, matches direct dependencies against the built-in registry, and adds missing opt-out variables to the write target. The default target is .env.
| Flag | Meaning |
|---|---|
--yes / -y | Skip confirmation (required when non-TTY or CI=true) |
--dry-run | Show what would be written; do not write |
--json | Machine-readable report (version: 1) |
--target <path> | Any env-file path, or stdout (default: .env) |
--example | Shorthand for --target .env.example (commit-safe opt-out template) |
init does not accept --only, --ignore, or --all; those flags belong to doctor and check.
stdout)KEY= placeholders in placeDO_NOT_TRACK=1stdout mode, writes pure KEY=VALUE lines to stdout and diagnostics to stderr--target stdout --json, keeps dotenv lines on stdout and sends the JSON report to stderr--example / .env.example like any other dotenv target; generated values contain no secretsdoctorPrints a per-library table and always exits 0. Installed libraries determine the summary. The human-readable table hides not found rows unless you pass --all.
| Flag | Meaning |
|---|---|
--json | Full machine-readable report |
--only <filter> | installed or failing |
--ignore <value> | Omit by id, display name, or package; repeatable |
--all | Include not-found rows in the human table |
doctor and check do not accept --yes, --dry-run, or --target.
--only filters libraries[] in JSON; summary retains the full post---ignore policy counts.
checkProduces the same output as doctor, but exits 1 if any installed, applicable library still has telemetry enabled after --ignore.
npx no-telemetry check
listDumps the full registry without reading package.json. Use it to discover coverage or feed registry data to another tool.
npx no-telemetry list
npx no-telemetry list --json
why <id>Explains one registry entry: environment variables, official docs, notes, and alternate satisfaction signals.
npx no-telemetry why next
npx no-telemetry why turbo --json
| Flag | Meaning |
|---|---|
--json | Pretty-printed JSON report (version: 1) |
--json=compact | One-line JSON for pipes |
--quiet / -q | Suppress human diagnostics; with --json, also selects compact output |
--version / -V | Print version |
--help / -h | Show help |
| Environment variable | Effect |
|---|---|
NO_COLOR | Disable ANSI colors when set to any non-empty value |
FORCE_COLOR | Force colors outside a TTY (0 disables them) |
| Code | Meaning |
|---|---|
0 | Success; doctor always, check when policy passes, or init completes |
1 | Policy failure; check found enabled telemetry, or interactive init was aborted |
2 | Tool or usage error; bad flags, missing package.json, or unconfirmed non-TTY init |
Library definitions live in src/registry.ts, the single source of truth. Each has a stable id such as next, prisma, or vercel for --ignore, why, and JSON output. Every environment variable is curated against official documentation.
Some tools honor a proprietary opt-out or DO_NOT_TRACK (for example, Turbo, Railway, and Supabase). Alternate signals use OR semantics by default. Entries with alternatePolicy: "fallback" use alternates only when the primary key is unset; this models tools such as GitHub CLI, where GH_TELEMETRY takes precedence. init still writes the primary tool-specific key plus DO_NOT_TRACK=1.
Registry entries are a discriminated union:
kind | Meaning |
|---|---|
opt-out | Telemetry is on by default; set env to disable it |
opt-in | Telemetry is off by default; enableWhen values mean it is on |
unsupported | No environment-variable opt-out; config or CLI action is required |
opt-out bindings may include accepts for multiple accepted values or non-empty semantics. Entries can also include alsoSatisfiedBy and alternatePolicy for additional signals.
The stable API is ESM-only and supports Node.js 18+:
import { scan, planInit, applyInit, failsCheck, buildReport, REGISTRY } from "no-telemetry";
const cwd = process.cwd();
const results = scan(cwd);
const failing = results.filter(failsCheck);
const report = buildReport(cwd, results);
| Export | Role |
|---|---|
scan / evaluate | Detect dependencies and evaluate status |
planInit / applyInit | Plan and apply idempotent dotenv writes |
failsCheck | Apply the check policy |
buildReport / buildErrorReport | Build the JSON DTO (version: 1) |
REGISTRY | Read the curated library data |
filterResults | Apply presentation filters |
LibraryResult.status uses machine-stable tokens: disabled, enabled, not_applicable, not_found, and unsupported. The CLI maps these to human labels such as ✓ disabled and - n/a.
Target-specific plans must be applied to the same target:
const target = ".env.local";
const plan = planInit(cwd, { target });
applyInit(cwd, plan, { target });
scan(cwd, process.env, { envFiles: [".env", ".env.local"] });
The easiest way to expand coverage is to add a typed entry to src/registry.ts:
Special matching or precedence rules should include a focused test. Config-only tools are welcome as unsupported entries so doctor can still surface them without changing user files.
See CONTRIBUTING.md for the full registry schema, development workflow, and pull request checklist.
pnpm install
pnpm run check
pnpm test
pnpm run build
The development toolchain runs on Node.js 22. The packed CLI and programmatic API are smoke-tested on Node.js 18, 20, and 22:
mkdir -p artifacts
pnpm pack --pack-destination artifacts
TARBALL=$(find artifacts -name '*.tgz' -type f -print -quit)
pnpm run test:package "$TARBALL" --tsc node_modules/.bin/tsc
Zero production dependencies. Runtime support: Node.js 18+.
15 commits
TypeScript
73.7%
JavaScript
26.3%