https://github.com/Silent-Watcher/spotenv
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
https://github.com/Silent-Watcher/spotenv
env environment-variable-processor environment-variables nodejs
Last synced: 4 months ago
JSON representation
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
- Host: GitHub
- URL: https://github.com/Silent-Watcher/spotenv
- Owner: Silent-Watcher
- License: mit
- Created: 2025-08-11T17:01:03.000Z (5 months ago)
- Default Branch: master
- Last Pushed: 2025-09-04T02:11:45.000Z (4 months ago)
- Last Synced: 2025-09-04T03:30:11.488Z (4 months ago)
- Topics: env, environment-variable-processor, environment-variables, nodejs
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/spotenv
- Size: 225 KB
- Stars: 36
- Watchers: 0
- Forks: 5
- Open Issues: 9
-
Metadata Files:
- Readme: readme.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
Awesome Lists containing this project
README
> **spotenv** — scan a JavaScript/TypeScript codebase for environment variable usage and generate a **safe** `.env.sample-filename` file.
---
## Why use spotenv
* Automatically discover the environment variables your code expects — great for onboarding, PRs, CI checks and documentation.
* Avoids manual errors: keeps `.env.sample-filename` in sync with code.
* Safer than naive tools: it uses AST-based extraction (Babel) for accurate detection rather than brittle regex-only scanning.
* Works with both JavaScript and TypeScript projects (parses TypeScript syntax via `@babel/parser` plugin).
---
## Key features
* Scans source files (`.js`, `.ts`, `.jsx`, `.tsx`, `.mjs`, `.cjs`).
* Two-pass strategy: fast text heuristics to find candidate files, then AST extraction for precision.
* Detects:
* `process.env.FOO`
* `process.env['FOO']` / `process.env["FOO"]`
* `const { FOO } = process.env` (with optional default values)
* `import.meta.env.FOO` (Vite)
* Flags dynamic usages (`process.env[someVar]`) for manual review.
* Avoids writing secrets or sensitive defaults to `sample-filename` (heuristic: keys containing `SECRET`, `TOKEN`, `KEY`, `PWD`, `PASSWORD`, `PRIVATE` are treated as sensitive).
* Watch mode — auto-regenerate `sample-filename` on file changes.
* Merge mode — preserve keys in an existing `sample-filename` while adding newly detected keys.
* You can customize a `.spotenv.json` file - the main configuration file of spotenv - to enable you to use spotenv without the cli flags.
* Multiple output formats: Generate `sample-filename` in env, JSON, or YAML format.
### Example Usage with a Configuration File
1. Create a `.spotenv.json` file in the root of your project.
2. 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.
In action, your configuration file should look like this:
```json
{
"dir": "/home/ubuntu/projects/project1",
"out": ".env.example",
"watch": false,
"merge": false,
"format": "json",
"ignore": [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
"**/.next/**",
"**/.turbo/**",
"**/.vercel/**",
"**/out/**"
]
}
```
**NOTE**: When you reference the environment file as shown above, it creates a new one in the current project root directory.
* With a properly configured file set up, you can run sponenv without cli options for the options specifically entered.
---
## When spotenv is useful (scenarios)
* New developer onboarding — provide a reliable `.env.sample-filename` for a repo.
* Open-source projects — maintainers can guarantee contributors see required env keys without exposing secrets.
* CI validation — check that required env keys are documented before deploying or running builds.
* Refactor time — ensure renamed/removed env keys are reflected in the sample-filename file.
---
## Installation
Install globally so the dotx command is available system-wide:
```bash
npm install -g spotenv
# or
yarn global add spotenv
```
> Or install as a project dependency and use with npx:
```bash
npm install --save-dev spotenv
# run
npx spotenv
```
> After installing globally, users can simply run `spotenv`.
---
## Usage
```bash
# run on current directory and write .env.example
spotenv -d . -o example
# Scan a specific project directory
spotenv -d /path/to/project
# Generate with custom filename (automatic extension handling)
spotenv -d . -o sample-filename
# Generate in different formats
spotenv -d . -f json -o env-config
spotenv -d . -f yml -o environment
# Watch and auto-regenerate (COMMING SOON!)
spotenv -w
# ➕ Generate TypeScript types (env.d.ts)
spotenv -d . -t
```
### CLI options
* `-d, --dir ` — project directory to scan (default: `.`)
* `-o, --out ` — output file path (default: `sample-filename`)
* `-w, --watch` — watch source files and auto-regenerate on change (COMMING SOON!)
* `-m, --merge` — merge results with an existing `.env.sample-filename` (keep existing keys)
* `--ignore ` — additional glob ignore patterns
* `-f, --format ` — output format for environment variables (env, json, yml) (default: `env`)
* `-t, --types` — generate TypeScript definition file (env.d.ts)
Examples:
```bash
# scan 'my-app' and write examples in repo root
spotenv -d ./my-app -o ./my-app/sample-filename
# Generate JSON format with custom filename
spotenv -d ./my-app -f json -o env-vars
# Generate YAML format for configuration
spotenv -d ./my-app -f yml -o config
# watch updates into existing example (COMMING SOON!)
spotenv -w
# Generate TypeScript types (env.d.ts)
spotenv -d ./my-app -t
```
---
## Output formats
spotenv supports multiple output formats to suit different use cases:
### env format (default)
Generated `.env.sample-filename` looks like this:
```env
# .env.sample-filename (generated)
# Add real values to .env — do NOT commit secrets to source control.
# used in: src/server.ts, src/config.ts
# default: 3000
PORT=
# used in: src/db.ts
DB_HOST=
# NOTE: dynamic keys detected (e.g. process.env[someVar]).
# Please review code and add any dynamic env keys manually.
```
### JSON format
For programmatic consumption or integration with other tools:
```json
[
{
"description": "used in: src/server.ts, src/config.ts, default: 3000",
"key": "PORT",
"value": ""
},
{
"description": "used in: src/db.ts",
"key": "DB_HOST",
"value": ""
}
]
```
### YAML format
For configuration management or documentation:
```yaml
# used in: src/server.ts, src/config.ts, default: 3000
PORT: ''
# used in: src/db.ts
DB_HOST: ''
```
### Notes
* Sensitive keys are shown but their defaults are omitted or redacted.
* If a key is detected multiple times, the file includes up to a few example source file locations.
* Custom filenames are automatically handled with appropriate extensions (`.env`, `.json`, `.yml`).
---
## Security & Best Practices
* **Never** commit real secrets into source control. `sample-filename` is meant to document keys, not store values.
* 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.
* The tool scans only source files; it **does not** inspect runtime environment or loaded `.env` files, so you won't accidentally reveal live secrets.
* Use `.env` (listed in `.gitignore`) for real values and keep it out of version control.
---
## Troubleshooting
###
### Dynamic keys
If 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.
---
## Implementation notes
* 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.
* Supported AST patterns include `MemberExpression` checks for `process.env`, `VariableDeclarator` for destructured env imports, and `MetaProperty` handling for `import.meta.env`.
* The generator intentionally avoids writing secret values and uses heuristics to decide which detected defaults are safe to show in the example.
---
## Extensibility & config
Ideas you can add later:
* Support framework-specific conventions: `NEXT_PUBLIC_*` (Next.js), `VITE_` prefixes, dotenv-safe validation, etc.
* Add more output formats (CSV, XML, etc.) for different use cases.
* Template customization for different project structures.
---
## Contributing
Contributions welcome! Please open issues for feature requests or bugs.
---
## License
MIT — see `LICENSE` for details.
---