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

env-precheck

v1.0.1

Published

Validate .env files and CI environment variables against annotated .env.example contracts. Catch missing variables and invalid types without logging secret values.

Readme

env-precheck

Catch broken configuration before your users do.

npm CI MIT

Turn .env.example into a deployment check. Keep values out of reports.

Zero runtime dependencies · CLI + TypeScript API · ESM + CommonJS · Node.js 20+

npx env-precheck

A missing database URL. An invalid port. A feature flag set to yes when the app expects true. These are small configuration mistakes that can break a deployment.

env-precheck compares your environment with .env.example, checks optional rules in comments, and exits before the next deployment step when something is wrong. It does not load variables into your application or change your files.

Integration recipes and tool-readable reference

See integration recipes for runnable patterns and selection criteria, release notes for changes, and llms.txt for a compact API index. The reference is ordinary documentation for developers and coding assistants; it does not require or guarantee automatic recommendations.

Start in 30 seconds

Install and commit a lockfile for reproducible CI:

npm install --save-dev env-precheck

Keep your existing .env.example. Every key is required by default; example values are not defaults. Add rules only where useful:

# @env type=port
PORT=3000

# @env type=url protocols=postgres,postgresql
DATABASE_URL=postgres://example:example@localhost/app

# @env minLength=32
SESSION_SECRET=replace-with-a-random-secret

# @env optional type=url protocols=https
ERROR_REPORTING_URL=

Then run:

npx env-precheck --env .env.production

Example failure output:

".env.production":1 invalid_type PORT: Value does not match the declared type.
".env.example":5 missing DATABASE_URL: Required variable is missing.
".env.production":2 too_short SESSION_SECRET: Value is shorter than the declared minimum length.
FAIL: 3 issue(s). Values omitted.

Variable names, source labels and line numbers are reported. Environment values, source excerpts, enum choices and parser exception text are not included.

Check the environment that will actually run

Layered files

npx env-precheck --env .env --env .env.production --env .env.local

Later files override earlier ones. A duplicate inside one file is an error, even if an overlay replaces it. Files are read literally; no framework-specific precedence is guessed.

CI secrets / container variables

npx env-precheck --process

This validates declared keys from the current process, without requiring a .env file. Unrelated variables such as PATH are ignored.

To combine files and process variables:

npx env-precheck --env .env.production --process

Process values win, including empty strings. Only own properties matching contract keys are read by the API. No values are written back to process.env.

Before deployment

{
  "scripts": {
    "check:env": "env-precheck --process",
    "predeploy": "npm run check:env"
  }
}

An npm predeploy hook runs before your existing npm run deploy script. For other deployment tools, run env-precheck as a separate prerequisite and honor its exit code.

Rule reference

Place # @env comments before a key. Multiple rule lines can precede one key. Blank lines and normal comments do not detach a pending rule. Rules reset after that key. Inline comments after assignments are ordinary comments, not rules.

| Rule | Meaning | | -------------------------- | --------------------------------------------------------------------------- | | required | Must exist and contain non-whitespace text; default | | optional | Missing or whitespace-only values are allowed; present values are validated | | type=string | Any nonempty text; default | | type=integer | Signed decimal integer within JavaScript's safe-integer range | | type=number | Finite decimal number; scientific notation allowed | | type=port | Decimal integer from 1 to 65535 | | type=boolean | Exactly true or false | | type=url | Absolute scheme://host URL with no whitespace | | type=enum values=a,b,c | Exact, case-sensitive choice; comma-separated, no spaces | | type=json | Valid JSON, including scalar JSON values | | min=1 max=100 | Inclusive bounds for integer, number or port | | minLength=32 | Minimum Unicode code-point count for strings | | protocols=https,postgres | Allowed lowercase URL schemes, without colons |

Example:

# @env type=enum values=development,test,production
NODE_ENV=development

# @env type=integer min=1 max=100
DB_POOL_SIZE=10

# @env type=json
FEATURES='{"search":true}'

Unknown rules, duplicate rules, conflicting rules, orphan annotations and an empty contract produce exit code 2, rather than silently skipping checks. A minimum string length checks length only; it does not measure password strength or randomness.

CLI

env-precheck [options]

--contract FILE   Contract file (default: .env.example)
--env FILE        Input file; repeat for ordered overlays (default: .env)
--process         Overlay declared process variables; alone, no .env is read
--strict          Reject file keys absent from the contract
--format FORMAT   text or json (default: text)
--help            Usage
--version         Installed version

| Exit | Meaning | | ---- | ----------------------------------------------------------------- | | 0 | All checks passed | | 1 | Configuration values failed validation | | 2 | Invalid contract, malformed/unreadable input or invalid CLI usage |

For machine-readable CI output:

npx env-precheck --process --format json
{
  "ok": false,
  "status": "fail",
  "checked": 1,
  "issues": [
    {
      "code": "missing",
      "source": ".env.example",
      "line": 1,
      "key": "DATABASE_URL",
      "message": "Required variable is missing."
    }
  ]
}

checked is the number of contract keys evaluated, including optional keys. On invalid input it is 0. --strict checks file keys only; unrelated process variables are always ignored. --format json also applies to argument errors regardless of flag order.

Programmatic API

import { checkEnv } from "env-precheck";
import { readFileSync } from "node:fs";

const report = checkEnv({
  contract: {
    name: ".env.example",
    text: readFileSync(".env.example", "utf8"),
  },
  files: [{ name: ".env", text: readFileSync(".env", "utf8") }],
  environment: process.env, // optional; overlays declared keys only
  strict: true,
});

if (!report.ok) {
  console.error(report); // diagnostics contain no configuration values
  process.exitCode = report.status === "invalid" ? 2 : 1;
}

CheckOptions, EnvSource, Report, Issue and IssueCode are exported types. CommonJS is supported with require('env-precheck'). The API returns a report, not coerced configuration values. Non-string values supplied by untyped callers are reported as invalid_value, without exposing the value. Filesystem I/O stays with the caller.

Deliberate boundaries

  • This is a predeployment check, not a dotenv loader, secret manager, source-code scanner or runtime schema replacement.
  • Checking a URL validates syntax and an optional protocol allowlist. It does not connect to a server, verify credentials, perform DNS lookup or prevent SSRF in your application.
  • The dotenv parser accepts ASCII identifiers, optional export, comments, BOM/CRLF, and single/double quoted multiline strings. Backticks, escaped quote delimiters and shell syntax are not supported. Backslashes stay literal: \n is not expanded into a newline. Use actual multiline quoted values when needed.
  • ${VAR} and $(command) are literal text. Nothing is expanded or executed. Validate the final process environment when your deployment system performs interpolation.
  • CLI files must be regular UTF-8 files, at most 1 MiB each. API source text is capped at 1 MiB UTF-16 code units per source. The CLI does not recursively scan directories or discover secret files.
  • Reports disclose key names and supplied source labels. Do not put secrets in either. Configuration values remain in process memory while checking; the tool does not erase memory or protect against a compromised runtime.
  • No configuration values are transmitted. The validator makes no network calls. Package installation through npm can, of course, access the registry.

There is no universal dotenv specification; see Node's dotenv documentation. Test against your loader's conventions, especially quoting and interpolation.

Related tools

dotenv-linter covers a broader set of dotenv linting and formatting checks. env-precheck focuses on using an annotated example file as a deployment contract, ordered overlays, process variables and reports that omit values. Existing runtime schema libraries remain useful for parsing configuration inside your application.

Development

npm ci
npm run check
npm run test:package
npm run demo
node bin/env-precheck.mjs --contract examples/app.env.example --env examples/app.env.invalid
# The last command intentionally exits with code 1.

CI tests Node.js 20, 22 and 24 on Linux, plus Node.js 22 on Windows. Package tests install the actual tarball into a temporary consumer and verify the CLI, both module formats and TypeScript declarations.

Contributing · Security · Changelog

MIT © Farhad Arjmand