{"id":30956098,"url":"https://github.com/Silent-Watcher/spotenv","last_synced_at":"2025-09-11T12:07:12.238Z","repository":{"id":309406377,"uuid":"1036172205","full_name":"Silent-Watcher/spotenv","owner":"Silent-Watcher","description":"Spotenv is a small, practical CLI tool that scans your project source code to find environment variables and produces a .env.example file containing the discovered keys","archived":false,"fork":false,"pushed_at":"2025-09-04T02:11:45.000Z","size":230,"stargazers_count":36,"open_issues_count":9,"forks_count":5,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-04T03:30:11.488Z","etag":null,"topics":["env","environment-variable-processor","environment-variables","nodejs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/spotenv","language":"TypeScript","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/Silent-Watcher.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","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":"2025-08-11T17:01:03.000Z","updated_at":"2025-09-04T02:53:42.000Z","dependencies_parsed_at":"2025-08-11T19:26:30.880Z","dependency_job_id":"2b4a2f26-f4cf-4ad4-a2c6-a5a0f606cd29","html_url":"https://github.com/Silent-Watcher/spotenv","commit_stats":null,"previous_names":["silent-watcher/spotenv"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Silent-Watcher/spotenv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Silent-Watcher%2Fspotenv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Silent-Watcher%2Fspotenv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Silent-Watcher%2Fspotenv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Silent-Watcher%2Fspotenv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Silent-Watcher","download_url":"https://codeload.github.com/Silent-Watcher/spotenv/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Silent-Watcher%2Fspotenv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274632637,"owners_count":25321251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"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":["env","environment-variable-processor","environment-variables","nodejs"],"created_at":"2025-09-11T12:03:56.950Z","updated_at":"2025-09-11T12:07:12.230Z","avatar_url":"https://github.com/Silent-Watcher.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"assets/spotenv.png\" alt=\"spotenv\" width=\"200\" height=\"200\"\u003e\n\n  \u003ch1\u003espotenv\u003c/h1\u003e\n\n  \u003cp\u003e\n\t\u003ca href=\"#features\"\u003efeatures\u003c/a\u003e •\n\t\u003ca href=\"#Installation\"\u003eInstallation\u003c/a\u003e •\n\t\u003ca href=\"#Usage\"\u003eUsage\u003c/a\u003e\n  \u003c/p\u003e\n\n\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/Silent-Watcher/spotenv/blob/master/LICENSE\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/license/Silent-Watcher/spotenv?color=#2fb64e\"license\"\u003e\n    \u003c/a\u003e\n  \u003c/p\u003e\n\n  \u003cp\u003e⭐️ Please press the star! It greatly helps development! ⭐️\u003c/p\u003e\n\n\u003c/div\u003e\n\n\u003e **spotenv** — scan a JavaScript/TypeScript codebase for environment variable usage and generate a **safe** `.env.sample-filename` file.\n\n\n---\n\n## Why use spotenv\n\n* Automatically discover the environment variables your code expects — great for onboarding, PRs, CI checks and documentation.\n* Avoids manual errors: keeps `.env.sample-filename` in sync with code.\n* Safer than naive tools: it uses AST-based extraction (Babel) for accurate detection rather than brittle regex-only scanning.\n* Works with both JavaScript and TypeScript projects (parses TypeScript syntax via `@babel/parser` plugin).\n\n---\n\n## Key features\n\n* Scans source files (`.js`, `.ts`, `.jsx`, `.tsx`, `.mjs`, `.cjs`).\n* Two-pass strategy: fast text heuristics to find candidate files, then AST extraction for precision.\n* Detects:\n\n  * `process.env.FOO`\n  * `process.env['FOO']` / `process.env[\"FOO\"]`\n  * `const { FOO } = process.env` (with optional default values)\n  * `import.meta.env.FOO` (Vite)\n* Flags dynamic usages (`process.env[someVar]`) for manual review.\n* Avoids writing secrets or sensitive defaults to `sample-filename` (heuristic: keys containing `SECRET`, `TOKEN`, `KEY`, `PWD`, `PASSWORD`, `PRIVATE` are treated as sensitive).\n* Watch mode — auto-regenerate `sample-filename` on file changes.\n* Merge mode — preserve keys in an existing `sample-filename` while adding newly detected keys.\n* You can customize a `.spotenv.json` file - the main configuration file of spotenv - to enable you to use spotenv without the cli flags.\n* Multiple output formats: Generate `sample-filename` in env, JSON, or YAML format.\n\n### Example Usage with a Configuration File\n1. Create a `.spotenv.json` file in the root of your project.\n2. Manually customize the individual flag options - `dir`, `out`, `watch`, `merge` and `ignore` - where `dir` refers to the target project directory to scan using both relative and absolute paths, `out` refers to the location of your `.env`, `.env.example`, `.env.local` file, specified to the directory of choice, while `watch` `merge` and `ignore` set the flags to watch, merge and list the directories to ignore scanning for environment variables respectively.\nIn action, your configuration file should look like this:\n\n```json\n{\n  \"dir\": \"/home/ubuntu/projects/project1\",\n  \"out\": \".env.example\",\n  \"watch\": false,\n  \"merge\": false,\n  \"format\": \"json\",\n  \"ignore\": [\n    \"**/node_modules/**\",\n    \"**/dist/**\",\n    \"**/build/**\",\n    \"**/.next/**\",\n    \"**/.turbo/**\",\n    \"**/.vercel/**\",\n    \"**/out/**\"\n  ]\n}\n```\n\n\n**NOTE**: When you reference the environment file as shown above, it creates a new one in the current project root directory.\n* With a properly configured file set up, you can run sponenv without cli options for the options specifically entered.\n---\n\n## When spotenv is useful (scenarios)\n\n* New developer onboarding — provide a reliable `.env.sample-filename` for a repo.\n* Open-source projects — maintainers can guarantee contributors see required env keys without exposing secrets.\n* CI validation — check that required env keys are documented before deploying or running builds.\n* Refactor time — ensure renamed/removed env keys are reflected in the sample-filename file.\n\n---\n\n## Installation\n\nInstall globally so the dotx command is available system-wide:\n\n```bash\nnpm install -g spotenv\n# or\nyarn global add spotenv\n```\n\n\u003e Or install as a project dependency and use with npx:\n\n```bash\nnpm install --save-dev spotenv\n# run\nnpx spotenv\n```\n\n\u003e After installing globally, users can simply run `spotenv`.\n---\n\n## Usage\n\n```bash\n# run on current directory and write .env.example\nspotenv -d . -o example\n\n# Scan a specific project directory\nspotenv -d /path/to/project\n\n# Generate with custom filename (automatic extension handling)\nspotenv -d . -o sample-filename\n\n# Generate in different formats\nspotenv -d . -f json -o env-config\nspotenv -d . -f yml -o environment\n\n# Watch and auto-regenerate (COMMING SOON!)\nspotenv -w\n\n# ➕ Generate TypeScript types (env.d.ts)\nspotenv -d . -t\n\n```\n\n### CLI options\n\n* `-d, --dir \u003cdir\u003e` — project directory to scan (default: `.`)\n* `-o, --out \u003cfile\u003e` — output file path (default: `sample-filename`)\n* `-w, --watch` — watch source files and auto-regenerate on change (COMMING SOON!)\n* `-m, --merge` — merge results with an existing `.env.sample-filename` (keep existing keys)\n* `--ignore \u003cpatterns...\u003e` — additional glob ignore patterns\n* `-f, --format \u003cextension\u003e` — output format for environment variables (env, json, yml) (default: `env`)\n* `-t, --types` — generate TypeScript definition file (env.d.ts)\nExamples:\n\n```bash\n# scan 'my-app' and write examples in repo root\nspotenv -d ./my-app -o ./my-app/sample-filename\n\n# Generate JSON format with custom filename\nspotenv -d ./my-app -f json -o env-vars\n\n# Generate YAML format for configuration\nspotenv -d ./my-app -f yml -o config\n\n# watch updates into existing example (COMMING SOON!)\nspotenv -w\n\n# Generate TypeScript types (env.d.ts)\nspotenv -d ./my-app -t\n```\n\n---\n\n## Output formats\n\nspotenv supports multiple output formats to suit different use cases:\n\n### env format (default)\n\nGenerated `.env.sample-filename` looks like this:\n\n```env\n# .env.sample-filename (generated)\n# Add real values to .env — do NOT commit secrets to source control.\n\n# used in: src/server.ts, src/config.ts\n# default: 3000\nPORT=\n\n# used in: src/db.ts\nDB_HOST=\n\n# NOTE: dynamic keys detected (e.g. process.env[someVar]).\n# Please review code and add any dynamic env keys manually.\n```\n\n### JSON format\n\nFor programmatic consumption or integration with other tools:\n\n```json\n[\n  {\n    \"description\": \"used in: src/server.ts, src/config.ts, default: 3000\",\n    \"key\": \"PORT\",\n    \"value\": \"\"\n  },\n  {\n    \"description\": \"used in: src/db.ts\",\n    \"key\": \"DB_HOST\",\n    \"value\": \"\"\n  }\n]\n```\n\n### YAML format\n\nFor configuration management or documentation:\n\n```yaml\n# used in: src/server.ts, src/config.ts, default: 3000\nPORT: ''\n\n# used in: src/db.ts\nDB_HOST: ''\n```\n\n### Notes\n\n* Sensitive keys are shown but their defaults are omitted or redacted.\n* If a key is detected multiple times, the file includes up to a few example source file locations.\n* Custom filenames are automatically handled with appropriate extensions (`.env`, `.json`, `.yml`).\n\n---\n\n## Security \u0026 Best Practices\n\n* **Never** commit real secrets into source control. `sample-filename` is meant to document keys, not store values.\n* Spotenv will **not** write literal string defaults into the example if the key looks sensitive (heuristic by name). However, you should manually review keys flagged sensitive.\n* The tool scans only source files; it **does not** inspect runtime environment or loaded `.env` files, so you won't accidentally reveal live secrets.\n* Use `.env` (listed in `.gitignore`) for real values and keep it out of version control.\n\n---\n\n## Troubleshooting\n\n###\n\n\n\n### Dynamic keys\n\nIf the tool reports dynamic keys (`process.env[someVar]`) it cannot statically resolve them — inspect those files manually and add keys to `.env.sample-filename` where appropriate.\n\n---\n\n## Implementation notes\n\n* The tool uses a **two-pass** approach: a lightweight text-based filter to find candidate files followed by AST parsing via `@babel/parser` and AST traversal (`@babel/traverse`) for accurate extraction.\n* Supported AST patterns include `MemberExpression` checks for `process.env`, `VariableDeclarator` for destructured env imports, and `MetaProperty` handling for `import.meta.env`.\n* The generator intentionally avoids writing secret values and uses heuristics to decide which detected defaults are safe to show in the example.\n\n---\n\n## Extensibility \u0026 config\n\nIdeas you can add later:\n\n* Support framework-specific conventions: `NEXT_PUBLIC_*` (Next.js), `VITE_` prefixes, dotenv-safe validation, etc.\n* Add more output formats (CSV, XML, etc.) for different use cases.\n* Template customization for different project structures.\n\n---\n\n## Contributing\n\nContributions welcome! Please open issues for feature requests or bugs.\n\n---\n\n## License\n\nMIT — see `LICENSE` for details.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003e\n    \u003csub\u003eBuilt with ❤️ by \u003ca href=\"https://github.com/Silent-Watcher\" target=\"_blank\"\u003eAli Nazari\u003c/a\u003e, for developers.\u003c/sub\u003e\n  \u003c/p\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/Silent-Watcher/spotenv\"\u003e⭐ Star us on GitHub\u003c/a\u003e •\n    \u003ca href=\"https://www.linkedin.com/in/alitte/\"\u003e🐦 Follow on Linkedin\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSilent-Watcher%2Fspotenv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSilent-Watcher%2Fspotenv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSilent-Watcher%2Fspotenv/lists"}