{"id":51008427,"url":"https://github.com/voidd0/envguard","last_synced_at":"2026-06-20T23:31:05.599Z","repository":{"id":353200375,"uuid":"1218360774","full_name":"voidd0/envguard","owner":"voidd0","description":"validate .env files against a schema. fail fast on missing keys.","archived":false,"fork":false,"pushed_at":"2026-04-29T06:14:12.000Z","size":22,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-15T20:46:11.263Z","etag":null,"topics":["cli","devtools","dotenv","env-validation","environment-variables","javascript","nodejs"],"latest_commit_sha":null,"homepage":"https://tools.voiddo.com/envguard/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voidd0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-22T19:52:06.000Z","updated_at":"2026-04-29T06:14:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/voidd0/envguard","commit_stats":null,"previous_names":["voidd0/envguard"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/voidd0/envguard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidd0%2Fenvguard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidd0%2Fenvguard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidd0%2Fenvguard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidd0%2Fenvguard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voidd0","download_url":"https://codeload.github.com/voidd0/envguard/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidd0%2Fenvguard/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34589204,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","devtools","dotenv","env-validation","environment-variables","javascript","nodejs"],"created_at":"2026-06-20T23:31:03.464Z","updated_at":"2026-06-20T23:31:05.594Z","avatar_url":"https://github.com/voidd0.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# envguard\n\n[![npm version](https://img.shields.io/npm/v/@v0idd0/envguard.svg?color=A0573A)](https://www.npmjs.com/package/@v0idd0/envguard)\n[![npm downloads](https://img.shields.io/npm/dw/@v0idd0/envguard.svg?color=1F1A14)](https://www.npmjs.com/package/@v0idd0/envguard)\n[![License: MIT](https://img.shields.io/badge/license-MIT-A0573A.svg)](LICENSE)\n[![Node ≥14](https://img.shields.io/badge/node-%E2%89%A514-1F1A14)](package.json)\n\n**[Homepage](https://tools.voiddo.com/envguard/?ref=envguard-readme)** · **[GitHub](https://github.com/voidd0/envguard)** · **[npm](https://www.npmjs.com/package/@v0idd0/envguard)** · **[All tools](https://tools.voiddo.com/?ref=envguard-catalog-readme)** · **[Contact](mailto:support@voiddo.com)**\n\n---\n\n**Validate `.env` files against a typed schema.** Catch `undefined`, `PORT=not-a-number`, missing secrets, and \"`.env` leaked into git\" — before your server tries to boot.\n\nFree forever gift from [vøiddo](https://voiddo.com).\n\n```\n$ envguard check\nchecking .env against .env.schema\n\nerrors:\n  ✗ PORT: invalid port: \"hello\"\n  ✗ DATABASE_URL: required but missing\nwarnings:\n  ⚠ LOG_LEVEL: missing, using default: info\n\n✗ failed. 2 error(s).\n```\n\n## Why envguard\n\n`dotenv` loads your `.env` into `process.env` without complaining about missing keys or bad types. You find out at runtime, usually at 2 AM. envguard fails at boot time — or better yet, at `pre-commit` time — so nothing that can't parse `PORT=3000` ever reaches production.\n\n- **21 typed validators** (url, uuid, semver, duration, json, ip, enum, regex, secret, ...)\n- **Constraints**: `port:min=1024,max=65535`, `string:min=8,max=64`\n- **Auto-schema** from existing `.env` (`envguard init`)\n- **Secret-leak scanner**: is `.env` in `.gitignore`? do keys/values smell like secrets?\n- **CI-ready**: `--json` envelope, proper exit codes, `--fail-if-leaked`\n\n## Install\n\n```bash\nnpm install -g @v0idd0/envguard\n```\n\nOr run ad-hoc with `npx`:\n\n```bash\nnpx -y @v0idd0/envguard check\n```\n\n## Quickstart\n\n```bash\n# Validate .env against .env.schema\nenvguard\n\n# First-time setup: auto-generate a schema from an existing .env\nenvguard init\n\n# Secret-leak scan (pre-commit gate)\nenvguard scan --fail-if-leaked\n\n# Diff two env files (e.g., dev vs prod)\nenvguard diff .env .env.prod\n\n# List variables with secrets masked\nenvguard list --mask-secrets\n\n# CI mode — JSON envelope, exit code 0/1\nenvguard check --json | jq .valid\n```\n\n## Commands\n\n| Command | Aliases | Description |\n|---------|---------|-------------|\n| `check` | `c` | Validate `.env` against `.env.schema` (default) |\n| `diff`  | `d` | Compare two `.env` files — what's only in one, what differs |\n| `init`  | `i` | Auto-generate schema from an existing `.env` |\n| `list`  | `l` | List variables in `.env` |\n| `scan`  | `s` | Secret-leak scan: gitignore check + secret shape detection |\n\n## Schema format\n\nOne line per var: `KEY=type[:constraints]` — or `KEY?` for optional, `KEY=default` for a plain default.\n\n```env\n# Required, typed\nDATABASE_URL=url\nPORT=port:min=1024,max=65535\nNODE_ENV=enum(development|staging|production)\nLOG_LEVEL=enum(debug|info|warn|error):info\nSESSION_TIMEOUT=duration               # 15m, 1h, 2d, 500ms\nUSER_ID=uuid\nAPP_VERSION=semver\nBIND_IP=ip\nAPI_KEY=secret:min=32\nALLOW_LIST=json\nTRACE_ID=regex:/^[a-z0-9]{16}$/\nDATA_DIR=dir                           # directory must exist\nCONFIG_FILE=file                       # file must exist\n\n# Optional (with ?)\nTELEMETRY_URL?=url\n\n# Plain default (no type)\nMAX_RETRIES=3\n```\n\n## Types (21)\n\n| Type | What it accepts |\n|------|-----------------|\n| `string` | any string; supports `min`/`max` length |\n| `number` | any numeric; supports `min`/`max` |\n| `integer` | whole numbers; supports `min`/`max` |\n| `boolean` | `true`/`false`/`1`/`0`/`yes`/`no`/`on`/`off` |\n| `url` | anything `new URL()` accepts |\n| `email` | `user@host.tld` |\n| `port` | 1–65535 (supports `min`/`max`) |\n| `ip` | IPv4 or IPv6 |\n| `ipv4` / `ipv6` | specific address family |\n| `uuid` | RFC 4122 UUID v1–v5 |\n| `semver` | `1.2.3`, `2.0.0-beta.1`, `1.0.0+build` |\n| `duration` | `15m`, `2h`, `500ms`, `1d`, `1w` |\n| `json` | parseable JSON |\n| `path` | any non-empty path string |\n| `dir` | path that resolves to a directory on disk |\n| `file` | path that resolves to a file on disk |\n| `regex` | `regex:/pattern/flags` |\n| `enum` | `enum(a\\|b\\|c)` |\n| `hex` | `[0-9a-fA-F]+` |\n| `secret` | any string ≥16 chars (overridable with `min=`) |\n\n## Options\n\n| Flag | Description |\n|------|-------------|\n| `-e, --env \u003cpath\u003e` | Path to `.env` file (default `.env`) |\n| `-s, --schema \u003cpath\u003e` | Path to schema file (default `.env.schema`) |\n| `-o, --output \u003cpath\u003e` | Output file (for `init`) |\n| `--strict` | Fail on extra variables not in the schema |\n| `--quiet` | Only print errors |\n| `--json` | Emit a JSON envelope (for CI) |\n| `--mask-secrets` | Redact likely-secret values in output |\n| `--fail-if-leaked` | `scan` exits with code `2` if `.env` is not git-ignored |\n| `-h, --help` | Show help |\n| `--version` | Show version |\n\n## Secret-leak scanner\n\n`envguard scan` walks your `.env` and reports:\n1. Whether `.env` is listed in `.gitignore` (green ✓ / red ✗).\n2. Every variable whose *name* looks like a secret (`SECRET`, `TOKEN`, `KEY`, `PASS`, `PRIVATE`, `CRED`, `AUTH`, `APIKEY`) or whose *value* looks like one (24+ high-entropy chars).\n\nWire it into `.git/hooks/pre-commit` or CI:\n\n```bash\nenvguard scan --fail-if-leaked || exit 1\n```\n\n## Exit codes\n\n| Code | Meaning |\n|------|---------|\n| `0`  | Validation passed / scan clean |\n| `1`  | Validation failed, file missing, or unknown command |\n| `2`  | `scan --fail-if-leaked` and `.env` is not in `.gitignore` |\n\n## Programmatic use\n\n```js\nconst {\n  parseEnvFile, parseSchema, validate, diff,\n  generateSchema, detectType, detectSecrets, looksLikeSecret,\n  validateValue, maskValue, parseDurationMs, isGitIgnored,\n} = require('@v0idd0/envguard/src/validator');\n\nconst envVars = parseEnvFile('.env');\nconst schema  = parseSchema('.env.schema');\nconst result  = validate(envVars, schema);\n\nif (!result.valid) {\n  console.error('bad env:', result.errors);\n  process.exit(1);\n}\n\n// Custom validators\nvalidateValue('15m', 'duration');                       // true\nvalidateValue('50', 'integer', { min: 1, max: 100 });   // true\nvalidateValue('prod', 'enum', { values: ['dev', 'prod'] }); // true\n\n// Secret scan\ndetectSecrets(envVars);        // [{ key, reason, length }, ...]\nisGitIgnored('.env');          // true / false / null\n```\n\n## From the same studio\n\nvøiddo builds sharp, free-forever CLIs for devs who are tired of paywalls:\n\n- [`@v0idd0/jsonyo`](https://tools.voiddo.com/jsonyo/?ref=envguard-related-jsonyo-readme) — JSON that yells at you when it's broken\n- [`@v0idd0/tokcount`](https://tools.voiddo.com/tokcount/?ref=envguard-related-tokcount-readme) — token counter for 60+ LLMs\n- [`@v0idd0/ctxstuff`](https://tools.voiddo.com/ctxstuff/?ref=envguard-related-ctxstuff-readme) — stuff a repo into an LLM context window\n- [`@v0idd0/promptdiff`](https://tools.voiddo.com/promptdiff/?ref=envguard-related-promptdiff-readme) — diff two prompts with token impact\n- [`@v0idd0/httpwut`](https://tools.voiddo.com/httpwut/?ref=envguard-related-httpwut-readme) — HTTP debugger with DNS/TCP/TLS phase timing\n- [`@v0idd0/gitstats`](https://tools.voiddo.com/gitstats/?ref=envguard-related-gitstats-readme) — local git analytics (hotspots, bus-factor)\n- [`@v0idd0/licenseme`](https://tools.voiddo.com/licenseme/?ref=envguard-related-licenseme-readme) — LICENSE generator + detector (18 licenses)\n\nFull catalog: [tools.voiddo.com](https://tools.voiddo.com/?ref=envguard-catalog-readme).\n\n## License\n\nMIT © [vøiddo](https://voiddo.com) — free forever, no asterisks.\n\n## Links\n\n- Docs: https://tools.voiddo.com/envguard/?ref=envguard-docs-readme\n- Source: https://github.com/voidd0/envguard\n- npm: https://npmjs.com/package/@v0idd0/envguard\n- Studio: https://voiddo.com/?ref=envguard-studio-readme\n- Issues: https://github.com/voidd0/envguard/issues\n- Support: support@voiddo.com\n\n---\n\nBuilt by [vøiddo](https://voiddo.com/) — a small studio shipping AI-flavoured products, free dev tools, Chrome extensions and weird browser games.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoidd0%2Fenvguard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoidd0%2Fenvguard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoidd0%2Fenvguard/lists"}