{"_id":"@arisrhiannon/envlint","_rev":"2-26373eecd5373977c6b6d47d9b0b5f6b","name":"@arisrhiannon/envlint","dist-tags":{"latest":"1.0.0"},"versions":{"0.2.0":{"name":"@arisrhiannon/envlint","version":"0.2.0","keywords":["dotenv","env","linter","validator","ci","cli","configuration","secrets","secret-detection","env-schema","dotenv-linter","environment-variables","github-actions"],"author":{"name":"Aris Rhiannon"},"license":"MIT","_id":"@arisrhiannon/envlint@0.2.0","maintainers":[{"name":"arisrhiannon","email":"12osemberg.arias@gmail.com"}],"homepage":"https://github.com/ArisRhiannon/envlint#readme","bugs":{"url":"https://github.com/ArisRhiannon/envlint/issues"},"bin":{"envlint":"dist/cli.js"},"dist":{"shasum":"078c30d109247b91158fdab1703a616aab2fb66c","tarball":"https://registry.npmjs.org/@arisrhiannon/envlint/-/envlint-0.2.0.tgz","fileCount":18,"integrity":"sha512-45iMmFHaRmqc3AqG1ym5h0OF2dqtB/VNHUYuWsfjBEFJ5bEfEzofqMbHR2BWkZlq9CMIq1CPQpWgEGBr7XI8lg==","signatures":[{"sig":"MEQCID4l5ZtgTn2KmJsPoDIAO7niw9eE038NcToWw0i5oMB8AiAz/KwmD4gMSTmGobNs97Qfn24/pcjgaVCkRc6SOx0VpA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28950},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"7b46bf635476cb29eae4030a2a3a91d354659bfc","scripts":{"test":"node --test","build":"tsc","start":"node src/cli.ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"arisrhiannon","email":"12osemberg.arias@gmail.com"},"repository":{"url":"git+https://github.com/ArisRhiannon/envlint.git","type":"git"},"_npmVersion":"11.11.0","description":"Zero-dependency CLI + library that lints .env files against .env.example: missing/duplicate/empty keys, unsafe .gitignore, secrets leaked into examples, and schema-as-comments type validation. Runs on Node, built for CI.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":">=5.7.0","@types/node":"^25.9.1"},"_npmOperationalInternal":{"tmp":"tmp/envlint_0.2.0_1780241490043_0.3756688744058605","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@arisrhiannon/envlint","version":"1.0.0","description":"Zero-dependency CLI + library that lints .env files against .env.example: missing/duplicate/empty keys, unsafe .gitignore, secrets leaked into examples, and schema-as-comments type validation. Runs on Node, built for CI.","type":"module","bin":{"envlint":"dist/cli.js"},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","test":"node --test","start":"node src/cli.ts","prepublishOnly":"npm run build"},"keywords":["dotenv","env","linter","validator","ci","cli","configuration","secrets","secret-detection","env-schema","dotenv-linter","environment-variables","github-actions"],"author":{"name":"Aris Rhiannon"},"license":"MIT","homepage":"https://github.com/ArisRhiannon/envlint#readme","repository":{"type":"git","url":"git+https://github.com/ArisRhiannon/envlint.git"},"bugs":{"url":"https://github.com/ArisRhiannon/envlint/issues"},"engines":{"node":">=18"},"publishConfig":{"access":"public"},"devDependencies":{"@types/node":"^25.9.1","typescript":">=5.7.0"},"gitHead":"eeaee5c5d1d5db1ca6471f5f310dffd3b8f2a751","_id":"@arisrhiannon/envlint@1.0.0","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-UIAd/pL60XkWqK5I43kyQa4FmnxVMbpND32uokbiwFWMwKMi99ouT8rUK7kNP3n59hlNTiIi/pR8W50XU9xCvg==","shasum":"674ffcd0587f37a41d04e486b9634aad598d18c1","tarball":"https://registry.npmjs.org/@arisrhiannon/envlint/-/envlint-1.0.0.tgz","fileCount":18,"unpackedSize":33286,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEHF9Gn0Vr958qYXSetfi4gKSiPerec6DvKI6IquXB8NAiEAvqiz68n8f+wrU3lKDQwnQ+WJnf5/D8xvL3c4eVkqA7Y="}]},"_npmUser":{"name":"arisrhiannon","email":"12osemberg.arias@gmail.com"},"directories":{},"maintainers":[{"name":"arisrhiannon","email":"12osemberg.arias@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/envlint_1.0.0_1780245777420_0.05149125764225615"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-31T15:31:29.787Z","modified":"2026-05-31T16:42:57.690Z","0.2.0":"2026-05-31T15:31:30.228Z","1.0.0":"2026-05-31T16:42:57.573Z"},"bugs":{"url":"https://github.com/ArisRhiannon/envlint/issues"},"author":{"name":"Aris Rhiannon"},"license":"MIT","homepage":"https://github.com/ArisRhiannon/envlint#readme","keywords":["dotenv","env","linter","validator","ci","cli","configuration","secrets","secret-detection","env-schema","dotenv-linter","environment-variables","github-actions"],"repository":{"type":"git","url":"git+https://github.com/ArisRhiannon/envlint.git"},"description":"Zero-dependency CLI + library that lints .env files against .env.example: missing/duplicate/empty keys, unsafe .gitignore, secrets leaked into examples, and schema-as-comments type validation. Runs on Node, built for CI.","maintainers":[{"name":"arisrhiannon","email":"12osemberg.arias@gmail.com"}],"readme":"# envlint\n\n> Zero-dependency CLI + library that validates your `.env` against `.env.example` — catch missing keys, duplicates, empty values and an unsafe `.gitignore` **before** they break a deploy.\n\n[![CI](https://github.com/ArisRhiannon/envlint/actions/workflows/ci.yml/badge.svg)](https://github.com/ArisRhiannon/envlint/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@arisrhiannon/envlint.svg)](https://www.npmjs.com/package/@arisrhiannon/envlint)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\nMisconfigured environment variables are one of the most common causes of \"works on my machine\" bugs and broken production deploys. `envlint` is a tiny, fast checker that drops into local workflows and CI.\n\n- **Runs on Node.** Pure JavaScript on install — `npx @arisrhiannon/envlint`, no Bun, Rust, or system binary required.\n- **Zero runtime dependencies.** Nothing pulled into your supply chain. Fully offline — never makes a network request.\n- **CI-friendly.** Clear exit codes, `--json`, and native GitHub Actions annotations.\n- **Safe by default.** Warns when `.env` isn't ignored by Git.\n- **Configurable.** Tune rules, required keys, and ignores via `.envlintrc.json`.\n- **Usable as a library.** Import `lint()` and wire it into your own tooling.\n\n### What makes envlint different\n\nThree things no other `.env` checker does — all static, offline, and zero-dependency:\n\n- 🧬 **Schema-as-comments.** Add `# @type`, `# @enum`, and `# @pattern` hints to\n  `.env.example` and envlint type-checks your `.env` values **in CI** — the safety\n  of `envalid`/`zod`-style validation with **no runtime and no dependency** in your app.\n- 🔓 **Leaked-secret detection.** `.env.example` is committed to git. envlint flags\n  real API keys and tokens accidentally pasted there (entropy + provider-prefix\n  heuristics) before they reach your history.\n- 🟢 **PR-native output.** `--format github` surfaces every finding as an inline\n  annotation on the exact line of the pull-request diff.\n\n## Install\n\n```sh\n# one-off, no install\nnpx @arisrhiannon/envlint\n\n# or install globally\nnpm install -g @arisrhiannon/envlint\n\n# or as a dev dependency / library\nnpm install -D @arisrhiannon/envlint\n```\n\nRequires Node.js >= 18.\n\n## Usage\n\n```sh\nenvlint                       # check ./.env against ./.env.example\nenvlint .env.production       # check a specific file\nenvlint .env .env.local       # check several files at once\nenvlint --example .env.sample # use a different example file\nenvlint --strict              # empty values become errors\nenvlint --json                # machine-readable output\nenvlint --format github       # inline annotations in GitHub Actions\nenvlint --quiet               # print errors only\n```\n\n### Example output\n\n```text\n$ envlint\n✖ missing-key: Missing key \"DATABASE_URL\"\n⚠ extra-key: Extra key \"DEBUG\" not in example (.env:7)\n⚠ empty-value: Empty value for \"API_URL\" (.env:4)\n\n1 error(s), 2 warning(s)\n```\n\n## Rules\n\n| Rule | Severity | Description |\n|------|----------|-------------|\n| `missing-key` | error | A key in the example (or `requiredKeys`) is absent from `.env` |\n| `duplicate-key` | error | The same key is defined more than once |\n| `gitignore-unsafe` | error | `.env` is not ignored by `.gitignore` |\n| `exposed-secret` | error | A value in the committed `.env.example` looks like a real secret |\n| `invalid-value` | error | A `.env` value violates a `@type`/`@enum`/`@pattern` annotation |\n| `extra-key` | warning | A key in `.env` is not present in the example file |\n| `empty-value` | warning | A key has an empty value (becomes an error with `--strict`) |\n| `invalid-annotation` | warning | An unrecognized `@directive` in the example (likely a typo) |\n\n## Schema annotations\n\nTurn `.env.example` into a typed contract using comments — validated statically,\nwith **zero runtime and zero dependencies** in your application:\n\n```sh\n# .env.example\n# @type url\nDATABASE_URL=\n# @type port\nPORT=\n# @enum development,production,test\nNODE_ENV=\n# @pattern ^sk-[A-Za-z0-9]{20,}$\nOPENAI_API_KEY=\n```\n\nNow `envlint` fails CI if `DATABASE_URL` isn't a URL, `PORT` isn't 1–65535,\n`NODE_ENV` is outside the set, or `OPENAI_API_KEY` doesn't match the pattern.\n\nSupported `@type`s: `url`, `int`, `number`, `port`, `bool`, `email`. Annotations\nattach to the next key; a blank line ends the block.\n\n## Configuration\n\nDrop a `.envlintrc.json` in your project root (or point at one with `--config`). CLI flags\ntake precedence over the config file.\n\n```json\n{\n  \"example\": \".env.example\",\n  \"strict\": false,\n  \"requiredKeys\": [\"DATABASE_URL\", \"SECRET_KEY\"],\n  \"ignoreKeys\": [\"NODE_ENV\"],\n  \"rules\": {\n    \"extra-key\": \"error\",\n    \"empty-value\": \"off\"\n  }\n}\n```\n\n- **`requiredKeys`** — keys that must be present even if you don't keep a full example file.\n- **`ignoreKeys`** — keys excluded from every check (useful for local-only variables).\n- **`rules`** — override any rule's severity to `\"error\"`, `\"warning\"`, or `\"off\"`.\n\n## Programmatic API\n\n```ts\nimport { lint } from \"@arisrhiannon/envlint\";\nimport { readFileSync } from \"node:fs\";\n\nconst result = lint({\n  env: readFileSync(\".env\", \"utf8\"),\n  example: readFileSync(\".env.example\", \"utf8\"),\n  strict: true,\n});\n\nconsole.log(result.errorCount, result.findings);\n```\n\n`lint`, `parseEnv`, `loadConfig`, and all types are exported. The package ships type declarations.\n\n## Use in CI\n\n```yaml\n# .github/workflows/env.yml\nname: env\non: [pull_request]\njobs:\n  envlint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 20\n      - run: npx --yes @arisrhiannon/envlint --strict --format github\n```\n\n## Exit codes\n\n| Code | Meaning |\n|------|---------|\n| `0` | No errors |\n| `1` | Errors found |\n| `2` | Usage error |\n\n## Limitations\n\nenvlint is a fast, offline, heuristic linter — not a secrets scanner or a runtime\nvalidator. Specifically:\n\n- **`exposed-secret` is best-effort.** It catches known token formats (AWS, GitHub,\n  Slack, Stripe, Google, JWTs, PEM keys) and high-entropy strings, but it is a\n  heuristic: it will miss low-entropy or unusual secrets, and **does not inspect\n  URLs or connection strings** (to avoid false positives on templates like\n  `postgres://user:password@localhost/db`). Use a dedicated scanner (e.g.\n  `gitleaks`, `trufflehog`) for real secret-leak prevention.\n- **`gitignore-unsafe` matches common patterns**, not the full gitignore grammar.\n- **Schema annotations are static checks**, not a runtime validator. Use `envalid`,\n  `zod`, or `env-schema` if you need typed env access inside your application.\n- envlint does not load, expand (`${VAR}`), or evaluate your environment.\n\n## Stability\n\n`1.x` follows [SemVer](https://semver.org/). The stable public surface is:\n\n- **CLI:** the documented flags, the `text`/`json`/`github` output formats, and the\n  exit codes (`0`/`1`/`2`).\n- **JSON output:** an array of `{ file, findings, errorCount, warningCount }`;\n  each finding has `{ severity, rule, message, key?, line? }`.\n- **Library:** the exports `lint`, `parseEnv`, `loadConfig`, `parseAnnotations`,\n  `validateValue`, `looksLikeSecret`, and their types.\n- **Rule names** are stable; new rules may be added in minor releases (default\n  severities of existing rules will not change in a way that turns a passing run\n  into a failing one within `1.x`).\n\nAnything not listed here is internal and may change without a major bump.\n\n## Development\n\nenvlint is written in TypeScript and runs on Node with no build step during development\n(Node strips the types). Building from source produces plain JavaScript for npm.\n\n```sh\nnpm install\nnpm test          # node --test (requires Node >= 22.18)\nnpm run typecheck # tsc --noEmit\nnpm run build     # emit dist/ (the published artifact)\n```\n\n## Contributing\n\nIssues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Please run\n`npm test` and `npm run typecheck` before submitting.\n\n## License\n\n[MIT](LICENSE) © 2026 Aris Rhiannon\n","readmeFilename":"README.md"}