dotenv-diff 2.6.1 → 2.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +10 -10
  3. package/dist/src/cli/run.d.ts.map +1 -1
  4. package/dist/src/cli/run.js.map +1 -1
  5. package/dist/src/commands/compare.d.ts.map +1 -1
  6. package/dist/src/commands/compare.js +5 -1
  7. package/dist/src/commands/compare.js.map +1 -1
  8. package/dist/src/commands/prompts/promptEnsureFiles.d.ts +9 -0
  9. package/dist/src/commands/prompts/promptEnsureFiles.d.ts.map +1 -1
  10. package/dist/src/commands/prompts/promptEnsureFiles.js +3 -3
  11. package/dist/src/commands/prompts/promptEnsureFiles.js.map +1 -1
  12. package/dist/src/commands/prompts/promptNoEnvScenario.js +1 -1
  13. package/dist/src/commands/prompts/promptNoEnvScenario.js.map +1 -1
  14. package/dist/src/commands/prompts/prompts.d.ts.map +1 -0
  15. package/dist/src/commands/prompts/prompts.js.map +1 -0
  16. package/dist/src/commands/scanUsage.js +4 -4
  17. package/dist/src/commands/scanUsage.js.map +1 -1
  18. package/dist/src/config/types.d.ts +85 -28
  19. package/dist/src/config/types.d.ts.map +1 -1
  20. package/dist/src/core/compare/parseAndFilterEnv.d.ts +4 -0
  21. package/dist/src/core/compare/parseAndFilterEnv.d.ts.map +1 -1
  22. package/dist/src/core/compare/parseAndFilterEnv.js.map +1 -1
  23. package/dist/src/core/compare/updateTotals.d.ts +5 -0
  24. package/dist/src/core/compare/updateTotals.d.ts.map +1 -1
  25. package/dist/src/core/compare/updateTotals.js.map +1 -1
  26. package/dist/src/core/fixEnv.d.ts +1 -11
  27. package/dist/src/core/fixEnv.d.ts.map +1 -1
  28. package/dist/src/core/fixEnv.js.map +1 -1
  29. package/dist/src/core/patterns.d.ts +7 -10
  30. package/dist/src/core/patterns.d.ts.map +1 -1
  31. package/dist/src/core/patterns.js +58 -4
  32. package/dist/src/core/patterns.js.map +1 -1
  33. package/dist/src/core/scan/scanFile.d.ts.map +1 -1
  34. package/dist/src/core/scan/scanFile.js +39 -35
  35. package/dist/src/core/scan/scanFile.js.map +1 -1
  36. package/dist/src/services/detectEnvExpirations.js +1 -1
  37. package/dist/src/services/detectEnvExpirations.js.map +1 -1
  38. package/dist/src/services/envDiscovery.d.ts.map +1 -1
  39. package/dist/src/services/envDiscovery.js +3 -9
  40. package/dist/src/services/envDiscovery.js.map +1 -1
  41. package/dist/src/services/printScanResult.d.ts +1 -15
  42. package/dist/src/services/printScanResult.d.ts.map +1 -1
  43. package/dist/src/services/printScanResult.js +27 -19
  44. package/dist/src/services/printScanResult.js.map +1 -1
  45. package/dist/src/services/processComparisonFile.d.ts +2 -5
  46. package/dist/src/services/processComparisonFile.d.ts.map +1 -1
  47. package/dist/src/services/processComparisonFile.js +13 -17
  48. package/dist/src/services/processComparisonFile.js.map +1 -1
  49. package/dist/src/ui/scan/printConsolelogWarning.d.ts +1 -2
  50. package/dist/src/ui/scan/printConsolelogWarning.d.ts.map +1 -1
  51. package/dist/src/ui/scan/printConsolelogWarning.js +1 -4
  52. package/dist/src/ui/scan/printConsolelogWarning.js.map +1 -1
  53. package/dist/src/ui/scan/printExampleWarnings.d.ts +1 -2
  54. package/dist/src/ui/scan/printExampleWarnings.d.ts.map +1 -1
  55. package/dist/src/ui/scan/printExampleWarnings.js +1 -6
  56. package/dist/src/ui/scan/printExampleWarnings.js.map +1 -1
  57. package/dist/src/ui/scan/printExpireWarnings.d.ts +1 -1
  58. package/dist/src/ui/scan/printExpireWarnings.d.ts.map +1 -1
  59. package/dist/src/ui/scan/printExpireWarnings.js +1 -4
  60. package/dist/src/ui/scan/printExpireWarnings.js.map +1 -1
  61. package/dist/src/ui/scan/printFrameworkWarnings.d.ts +1 -2
  62. package/dist/src/ui/scan/printFrameworkWarnings.d.ts.map +1 -1
  63. package/dist/src/ui/scan/printFrameworkWarnings.js +2 -7
  64. package/dist/src/ui/scan/printFrameworkWarnings.js.map +1 -1
  65. package/dist/src/ui/scan/printHealthScore.d.ts.map +1 -1
  66. package/dist/src/ui/scan/printHealthScore.js +8 -4
  67. package/dist/src/ui/scan/printHealthScore.js.map +1 -1
  68. package/dist/src/ui/scan/printInconsistentNamingWarning.d.ts +1 -2
  69. package/dist/src/ui/scan/printInconsistentNamingWarning.d.ts.map +1 -1
  70. package/dist/src/ui/scan/printInconsistentNamingWarning.js +2 -3
  71. package/dist/src/ui/scan/printInconsistentNamingWarning.js.map +1 -1
  72. package/dist/src/ui/scan/printMissing.d.ts +1 -3
  73. package/dist/src/ui/scan/printMissing.d.ts.map +1 -1
  74. package/dist/src/ui/scan/printMissing.js +1 -5
  75. package/dist/src/ui/scan/printMissing.js.map +1 -1
  76. package/dist/src/ui/scan/printSecrets.d.ts +1 -2
  77. package/dist/src/ui/scan/printSecrets.d.ts.map +1 -1
  78. package/dist/src/ui/scan/printSecrets.js +1 -4
  79. package/dist/src/ui/scan/printSecrets.js.map +1 -1
  80. package/dist/src/ui/scan/printStats.d.ts +2 -17
  81. package/dist/src/ui/scan/printStats.d.ts.map +1 -1
  82. package/dist/src/ui/scan/printStats.js +2 -2
  83. package/dist/src/ui/scan/printStats.js.map +1 -1
  84. package/dist/src/ui/scan/printUnused.d.ts +1 -2
  85. package/dist/src/ui/scan/printUnused.d.ts.map +1 -1
  86. package/dist/src/ui/scan/printUnused.js +1 -4
  87. package/dist/src/ui/scan/printUnused.js.map +1 -1
  88. package/dist/src/ui/scan/printUppercaseWarning.d.ts +1 -2
  89. package/dist/src/ui/scan/printUppercaseWarning.d.ts.map +1 -1
  90. package/dist/src/ui/scan/printUppercaseWarning.js +2 -3
  91. package/dist/src/ui/scan/printUppercaseWarning.js.map +1 -1
  92. package/dist/src/ui/scan/scanJsonOutput.d.ts +2 -8
  93. package/dist/src/ui/scan/scanJsonOutput.d.ts.map +1 -1
  94. package/dist/src/ui/scan/scanJsonOutput.js.map +1 -1
  95. package/dist/src/ui/shared/printAutoFix.d.ts +2 -13
  96. package/dist/src/ui/shared/printAutoFix.d.ts.map +1 -1
  97. package/dist/src/ui/shared/printAutoFix.js +3 -5
  98. package/dist/src/ui/shared/printAutoFix.js.map +1 -1
  99. package/docs/assets/demo1.gif +0 -0
  100. package/docs/assets/success1.png +0 -0
  101. package/docs/configuration_and_flags.md +726 -0
  102. package/docs/expiration_warnings.md +111 -0
  103. package/docs/frameworks/index.md +24 -0
  104. package/docs/frameworks/nextjs_warnings.md +56 -0
  105. package/docs/frameworks/sveltekit_warnings.md +130 -0
  106. package/docs/git_hooks_ci.md +51 -0
  107. package/docs/ignore_comments.md +82 -0
  108. package/docs/index.md +87 -0
  109. package/docs/monorepo_support.md +63 -0
  110. package/package.json +11 -9
  111. package/dist/src/ui/prompts.d.ts.map +0 -1
  112. package/dist/src/ui/prompts.js.map +0 -1
  113. /package/dist/src/{ui → commands/prompts}/prompts.d.ts +0 -0
  114. /package/dist/src/{ui → commands/prompts}/prompts.js +0 -0
@@ -0,0 +1,111 @@
1
+ # Expiration Warnings
2
+
3
+ Expiration warnings help you track time-limited environment variables such as temporary API keys, tokens, and credentials.
4
+
5
+ By annotating a key with an expiration date, `dotenv-diff` can:
6
+
7
+ - warn when a key is expired
8
+ - warn when a key is close to expiration
9
+ - fail the process in `--strict` mode
10
+
11
+ ## Syntax
12
+
13
+ Add an expiration annotation directly above the variable:
14
+
15
+ ```env
16
+ # @expire 2026-12-31
17
+ TEMP_API_TOKEN=abc123
18
+ ```
19
+
20
+ Supported annotation styles:
21
+
22
+ ```env
23
+ # @expire 2026-12-31
24
+ TOKEN_A=...
25
+
26
+ // @expire 2026-12-31
27
+ TOKEN_B=...
28
+
29
+ @expire 2026-12-31
30
+ TOKEN_C=...
31
+
32
+ # expire 2026-12-31
33
+ TOKEN_D=...
34
+ ```
35
+
36
+ ### Rules
37
+
38
+ - Date format must be `YYYY-MM-DD`
39
+ - `@` is optional (`expire 2026-12-31` also works)
40
+ - The annotation applies to the **next env key only**
41
+ - If no key follows, no warning is created
42
+
43
+ ## Warning output
44
+
45
+ When expiration annotations are found, CLI output includes an `Expiration warnings` section.
46
+
47
+ Severity is shown from `daysLeft`:
48
+
49
+ - `< 0`: expired (`EXPIRED ... days ago`)
50
+ - `0`: `EXPIRES TODAY`
51
+ - `1`: `expires tomorrow`
52
+ - `2-3`: urgent warning
53
+ - `4-7`: warning
54
+ - `> 7`: still shown as informational warning
55
+
56
+ ## Strict mode
57
+
58
+ In strict mode, expiration warnings are treated as blocking warnings and return exit code `1`.
59
+
60
+ ```bash
61
+ dotenv-diff --strict
62
+ ```
63
+
64
+ If expiration warnings exist, strict mode includes them in the strict error summary.
65
+
66
+ ## Enable / disable
67
+
68
+ Expiration warnings are enabled by default.
69
+
70
+ Disable via CLI:
71
+
72
+ ```bash
73
+ dotenv-diff --no-expire-warnings
74
+ ```
75
+
76
+ Or disable in `dotenv-diff.config.json`:
77
+
78
+ ```json
79
+ {
80
+ "expireWarnings": false
81
+ }
82
+ ```
83
+
84
+ You can also force-enable explicitly:
85
+
86
+ ```bash
87
+ dotenv-diff --expire-warnings
88
+ ```
89
+
90
+ ## JSON output
91
+
92
+ With `--json`, expiration warnings are returned in the `expireWarnings` field:
93
+
94
+ ```json
95
+ {
96
+ "expireWarnings": [
97
+ {
98
+ "key": "TEMP_API_TOKEN",
99
+ "date": "2026-12-31",
100
+ "daysLeft": 30
101
+ }
102
+ ]
103
+ }
104
+ ```
105
+
106
+ ## Best practices
107
+
108
+ - Use `YYYY-MM-DD` consistently
109
+ - Keep expiration comments immediately above the key they belong to
110
+ - Add a short comment describing why the key expires
111
+ - Combine with `--strict` in CI/CD to catch expired credentials early
@@ -0,0 +1,24 @@
1
+ # Framework-Specific Warnings
2
+
3
+ This section explains which framework-specific environment variable are currently supported and how it works.
4
+
5
+ ---
6
+
7
+ ## Supported frameworks
8
+
9
+ - [SvelteKit warnings](./sveltekit_warnings.md)
10
+ - [Next.js warnings](./nextjs_warnings.md)
11
+
12
+ ---
13
+
14
+ ## Framework detection
15
+
16
+ dotenv-diff detects framework rules automatically from `package.json` in your current working directory.
17
+
18
+ E.g.
19
+
20
+ - If `@sveltejs/kit` is present, SvelteKit rules are enabled.
21
+ - If `next` is present, Next.js rules are enabled.
22
+ - If neither is detected, framework-specific warnings are skipped.
23
+
24
+ ---
@@ -0,0 +1,56 @@
1
+ # Next.js warnings
2
+
3
+ `dotenv-diff` includes Next.js-specific rules to catch unsafe or invalid environment variable usage.
4
+
5
+ This page reflects the currently implemented rule behavior.
6
+
7
+ ## 1 Client code must use `NEXT_PUBLIC_` variables only
8
+
9
+ When a file is treated as client code (`"use client"` or Pages Router client files), non-`NEXT_PUBLIC_` variables trigger a warning.
10
+
11
+ ```tsx
12
+ "use client";
13
+ console.log(process.env.SECRET_TOKEN);
14
+ ```
15
+
16
+ Warning:
17
+
18
+ `Server-only variable accessed from client code`
19
+
20
+ ## 2 `import.meta.env` is not supported in Next.js
21
+
22
+ ```ts
23
+ console.log(import.meta.env.PRIVATE_KEY);
24
+ ```
25
+
26
+ Warning:
27
+
28
+ `Next.js uses process.env, not import.meta.env (Vite syntax)`
29
+
30
+ ## 3 Sensitive-looking `NEXT_PUBLIC_` names trigger exposure warnings
31
+
32
+ If a `NEXT_PUBLIC_` variable contains `SECRET`, `PRIVATE`, or `PASSWORD`, a warning is produced.
33
+
34
+ ```ts
35
+ console.log(process.env.NEXT_PUBLIC_SECRET_PASSWORD);
36
+ ```
37
+
38
+ Warning:
39
+
40
+ `Potential sensitive environment variable exposed to the browser`
41
+
42
+ ## What is allowed
43
+
44
+ Server files (for example API routes and other server-only code) can use private environment variables without framework warnings.
45
+
46
+ ## Summary of rules
47
+
48
+ - Client code → only `NEXT_PUBLIC_*`
49
+ - `import.meta.env` → not valid in Next.js
50
+ - Sensitive names in `NEXT_PUBLIC_*` → warning
51
+
52
+ ## Best practices
53
+
54
+ - Use `NEXT_PUBLIC_*` only for browser-safe values
55
+ - Keep secrets in server-only code paths
56
+ - Do not use `import.meta.env` in Next.js projects
@@ -0,0 +1,130 @@
1
+ # SvelteKit warnings
2
+
3
+ `dotenv-diff` includes SvelteKit-specific rules for invalid or unsafe environment variable usage.
4
+
5
+ This page documents the exact warning behavior currently implemented.
6
+
7
+ ## 1 `import.meta.env` must use `VITE_` prefix
8
+
9
+ ```ts
10
+ import.meta.env.PUBLIC_URL
11
+ ```
12
+
13
+ Warning:
14
+
15
+ `Variables accessed through import.meta.env must start with "VITE_"`
16
+
17
+ Correct usage:
18
+
19
+ ```ts
20
+ import.meta.env.VITE_PUBLIC_URL
21
+ ```
22
+
23
+ ## 2 `process.env` should only be used in server files
24
+
25
+ ```ts
26
+ process.env.VITE_SECRET
27
+ ```
28
+
29
+ Warning:
30
+
31
+ `process.env should only be used in server files`
32
+
33
+ ## 3 `$env/dynamic/private` cannot be used in client-side code
34
+
35
+ ```svelte
36
+ <script lang="ts">
37
+ import { env } from '$env/dynamic/private';
38
+ console.log(env.SECRET_KEY);
39
+ </script>
40
+ ```
41
+
42
+ Warning:
43
+
44
+ `$env/dynamic/private cannot be used in client-side code`
45
+
46
+ ## 4 `$env/dynamic/private` variables must not start with `PUBLIC_`
47
+
48
+ ```ts
49
+ import { env } from '$env/dynamic/private';
50
+ console.log(env.PUBLIC_API_URL);
51
+ ```
52
+
53
+ Warning:
54
+
55
+ `$env/dynamic/private variables must not start with "PUBLIC_"`
56
+
57
+ ## 5 `$env/dynamic/public` variables must start with `PUBLIC_`
58
+
59
+ ```ts
60
+ import { env } from '$env/dynamic/public';
61
+ console.log(env.API_URL);
62
+ ```
63
+
64
+ Warning:
65
+
66
+ `$env/dynamic/public variables must start with "PUBLIC_"`
67
+
68
+ ## 6 `$env/static/private` variables must not start with `PUBLIC_`
69
+
70
+ ```ts
71
+ import { PUBLIC_KEY } from '$env/static/private';
72
+ ```
73
+
74
+ Warning:
75
+
76
+ `$env/static/private variables must not start with "PUBLIC_"`
77
+
78
+ ## 7 `$env/static/private` cannot be used in client-side code
79
+
80
+ ```svelte
81
+ <script lang="ts">
82
+ import { SECRET_KEY } from '$env/static/private';
83
+ </script>
84
+ ```
85
+
86
+ Warning:
87
+
88
+ `$env/static/private variables cannot be used in client-side code`
89
+
90
+ ## 8 `$env/static/public` variables must start with `PUBLIC_`
91
+
92
+ ```ts
93
+ import { API_URL } from '$env/static/public';
94
+ ```
95
+
96
+ Warning:
97
+
98
+ `$env/static/public variables must start with "PUBLIC_"`
99
+
100
+ ## 9 Sensitive-looking `PUBLIC_` / `VITE_` names trigger exposure warnings
101
+
102
+ If a client-exposed name contains `SECRET`, `PRIVATE`, or `PASSWORD`, a warning is produced.
103
+
104
+ ```svelte
105
+ <script lang="ts">
106
+ import { env } from '$env/dynamic/public';
107
+ console.log(env.PUBLIC_SECRET_PASSWORD);
108
+ </script>
109
+ ```
110
+
111
+ Warning:
112
+
113
+ `Potential sensitive environment variable exposed to the browser`
114
+
115
+ ## Summary of rules
116
+
117
+ - `import.meta.env` → must use `VITE_*`
118
+ - `process.env` → server files only
119
+ - `$env/dynamic/private` → server-only, never `PUBLIC_*`
120
+ - `$env/dynamic/public` → must use `PUBLIC_*`
121
+ - `$env/static/private` → server-only, never `PUBLIC_*`
122
+ - `$env/static/public` → must use `PUBLIC_*`
123
+ - Sensitive client-exposed names (`PUBLIC_*`/`VITE_*`) → warning
124
+
125
+ ## Best practices
126
+
127
+ - Use `PUBLIC_*` only for values intended for the browser
128
+ - Use `VITE_*` only via `import.meta.env`
129
+ - Keep private variables in server-only code
130
+ - Never expose secrets via `PUBLIC_*` or `VITE_*`
@@ -0,0 +1,51 @@
1
+ # Git Hooks and CI/CD
2
+
3
+ `dotenv-diff` is a CLI-first tool and does not manage git hooks or CI workflows by itself.
4
+
5
+ Instead, it is built to integrate cleanly with your existing tooling, such as Husky pre-commit hooks and GitHub Actions.
6
+
7
+ ## Using dotenv-diff as a pre-commit hook
8
+
9
+ Running `dotenv-diff` before each commit helps catch missing, unused, and misused environment variables early.
10
+
11
+ A common setup is Husky + lint-staged, where `dotenv-diff` runs automatically on commit.
12
+
13
+ ## Running dotenv-diff in GitHub Actions
14
+
15
+ Use `dotenv-diff` in CI to validate environment variable consistency on pull requests.
16
+
17
+ This is especially useful to keep `.env.example` in sync with real usage in code.
18
+
19
+ ### Example GitHub Action
20
+
21
+ `.github/workflows/dotenv-diff.yml`
22
+
23
+ ```yaml
24
+ name: dotenv-diff
25
+
26
+ on: [pull_request]
27
+
28
+ jobs:
29
+ env-validation:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v6
33
+ - uses: actions/setup-node@v6
34
+ - run: npm ci
35
+ - run: npx dotenv-diff --example .env.example --strict
36
+ ```
37
+
38
+ ## Why use this in hooks and CI
39
+
40
+ - Prevent commits that introduce undocumented environment variables
41
+ - Catch framework-specific env usage issues early
42
+ - Keep `.env.example` accurate across contributors and pull requests
43
+
44
+ ## Best practices
45
+
46
+ - Use `--example` to validate against your reference file
47
+ - Use `--strict` in CI for fail-fast behavior on warnings
48
+ - Keep hook checks fast and predictable
49
+ - Pair with monorepo patterns (`--include-files`) where relevant
50
+
51
+ ---
@@ -0,0 +1,82 @@
1
+ # Ignore Comments
2
+
3
+ dotenv-diff can skip certain lines or code sections from being flagged during scanning. This is helpful when you know a specific warning is safe in your source code.
4
+
5
+ Ignore comments work for both secret detection and environment variable usage scanning, allowing you to suppress false positives while maintaining security in the rest of your codebase.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Single Line Ignore](#single-line-ignore)
10
+ - [Block Ignore](#block-ignore)
11
+ - [When to Use](#when-to-use)
12
+
13
+ ## Single Line Ignore
14
+
15
+ You can ignore a single line by adding an inline comment with `dotenv-diff-ignore`.
16
+
17
+ ### JavaScript/TypeScript
18
+
19
+ ```typescript
20
+ const apiKey = 'safe_secret_123123123'; // dotenv-diff-ignore
21
+ ```
22
+
23
+ This will suppress potential secret warnings for this specific line but still allow dotenv-diff to report other issues elsewhere in the file.
24
+
25
+ ### JavaScript Block Comments
26
+
27
+ ```javascript
28
+ const url = 'https://safe.example.com'; /* dotenv-diff-ignore */
29
+ ```
30
+
31
+ ### HTML
32
+
33
+ ```html
34
+ <a href="https://safe.example.com">Link</a> <!-- dotenv-diff-ignore -->
35
+ ```
36
+
37
+ ### JSX/TSX Files
38
+
39
+ ```ts
40
+ <p>Database: {process.env.DATABASE_URL}</p> {/* <!-- dotenv-diff-ignore --> */}
41
+ ```
42
+
43
+ ## Block Ignore
44
+
45
+ You can ignore entire sections of code using start and end markers. All lines between the markers will be skipped during scanning.
46
+
47
+ ### HTML/JSX/TSX
48
+
49
+ ```html
50
+ <!-- dotenv-diff-ignore-start -->
51
+ <p>Hardcoded data, images or links that are safe to ignore</p>
52
+ <img src="https://cdn.safe-service.com/image.png" />
53
+ <a href="https://legacy-system.com/api">Legacy API</a>
54
+ <!-- dotenv-diff-ignore-end -->
55
+ ```
56
+
57
+ ```ts
58
+ // dotenv-diff-ignore-start
59
+ const legacyApiKey = 'legacy_secret_456456456';
60
+ const safeKey = process.env.SAFE_KEY;
61
+ // dotenv-diff-ignore-end
62
+ ```
63
+
64
+ This is particularly useful for:
65
+
66
+ - Legacy code sections that can't be easily refactored
67
+ - Generated HTML or markup with safe hardcoded values
68
+ - Documentation or example code embedded in your source
69
+ - Third-party integrations with known safe URLs
70
+
71
+ Ignore markers are case-insensitive.
72
+
73
+ ## Alternative Configuration
74
+
75
+ If you need to ignore entire files, folders, or key patterns globally, consider using configuration options instead:
76
+
77
+ - `--exclude-files <patterns>` - Skip entire files or directories from scanning
78
+ - `--ignore <keys>` - Ignore specific environment variable keys
79
+ - `--ignore-regex <patterns>` - Ignore keys matching regex patterns
80
+ - `--ignore-urls <list>` - Ignore specific URLs during secret detection
81
+
82
+ See the [Configuration and Flags](./configuration_and_flags.md) documentation for more details.
package/docs/index.md ADDED
@@ -0,0 +1,87 @@
1
+ # dotenv-diff Documentation
2
+
3
+ Welcome to the official documentation for `dotenv-diff`.
4
+
5
+ `dotenv-diff` scans your codebase for environment variable usage and compares it against your `.env` and/or `.env.example` files.
6
+
7
+ It helps you:
8
+
9
+ - Detect missing environment variables
10
+ - Detect unused variables in your `.env` files
11
+ - Prevent runtime crashes caused by undefined `process.env` usage
12
+ - Enforce consistent environment configuration across teams
13
+ - Apply framework-specific validation rules (SvelteKit, Next.js, etc.)
14
+
15
+ The tool is designed to be fast, CI-friendly, and safe to run in large projects and monorepos.
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ Install:
22
+
23
+ ```bash
24
+ npm install dotenv-diff
25
+ ```
26
+
27
+ Run:
28
+
29
+ ```bash
30
+ npx dotenv-diff
31
+ ```
32
+
33
+ ---
34
+
35
+ The extension recognises the following patterns:
36
+
37
+ ```typescript
38
+ // Node.js – dot and bracket notation
39
+ process.env.MY_KEY
40
+ process.env["MY_KEY"]
41
+ process.env['MY_KEY']
42
+
43
+ // Node.js – destructuring
44
+ const { MY_KEY } = process.env
45
+ const { MY_KEY: alias, OTHER_KEY = "fallback" } = process.env
46
+
47
+ // Vite / import.meta
48
+ import.meta.env.MY_KEY
49
+ import.meta.env["MY_KEY"]
50
+ import.meta.env['MY_KEY']
51
+
52
+ // SvelteKit – dynamic (env object)
53
+ import { env } from '$env/dynamic/private';
54
+ import { env } from '$env/dynamic/public';
55
+ env.MY_KEY
56
+
57
+ // SvelteKit – static (named imports)
58
+ import { MY_KEY } from '$env/static/private';
59
+ import { MY_KEY } from '$env/static/public';
60
+ MY_KEY
61
+ ```
62
+
63
+ Only `UPPER_CASE` key names are matched, which is the standard convention for environment variables.
64
+
65
+ Default scanned file types: .ts, .js, jsx, tsx, vue, .mjs, .cjs, .svelte
66
+
67
+ ---
68
+
69
+ ## Table of Contents
70
+
71
+ | Document | Description |
72
+ |---|---|
73
+ | [Configuration and Flags](./configuration_and_flags.md) | Full CLI/config reference for options and behavior |
74
+ | [Expiration Warnings](./expiration_warnings.md) | How `@expire` annotations work and strict mode integration |
75
+ | [Ignore Comments](./ignore_comments.md) | Suppress false positives with inline/block ignore markers |
76
+ | [Monorepo Support](./monorepo_support.md) | Scan shared packages and cross-folder usage in monorepos |
77
+ | [Git Hooks and CI/CD](./git_hooks_ci.md) | Integrate dotenv-diff with Husky, lint-staged, and GitHub Actions |
78
+ | [Framework Warnings (Index)](./frameworks/index.md) | Framework detection and links to supported framework rules |
79
+ | [SvelteKit warnings](./frameworks/sveltekit_warnings.md) | SvelteKit-specific env validation rules |
80
+ | [Next.js warnings](./frameworks/nextjs_warnings.md) | Next.js-specific env validation rules |
81
+
82
+ ---
83
+
84
+ ## Quick links
85
+
86
+ - [Issue Tracker](https://github.com/Chrilleweb/dotenv-diff/issues)
87
+ - [CHANGELOG](../CHANGELOG.md)
@@ -0,0 +1,63 @@
1
+ # Monorepo Support
2
+
3
+ In monorepos with multiple apps and shared packages, environment variables are often referenced across folder boundaries.
4
+
5
+ `dotenv-diff` supports this by scanning from your current app and letting you extend the scan scope to shared folders.
6
+
7
+ ## Scanning shared packages
8
+
9
+ By default, `dotenv-diff` scans from the current working directory.
10
+
11
+ In a monorepo, use `--include-files` to add shared package paths:
12
+
13
+ ```json
14
+ {
15
+ "scripts": {
16
+ "dotenv-diff": "dotenv-diff --example .env.example --include-files '../../packages/**/*'"
17
+ }
18
+ }
19
+ ```
20
+
21
+ ### What this does
22
+
23
+ - Scans the current application
24
+ - Compares your environment variables against `.env.example`
25
+ - Includes shared packages from the monorepo (for example `../../packages/**/*`)
26
+ - Detects env usage across app + shared code
27
+
28
+ ## Using a configuration file
29
+
30
+ For larger monorepos, move file patterns and ignores to `dotenv-diff.config.json`:
31
+
32
+ ```json
33
+ {
34
+ "example": ".env.example",
35
+ "includeFiles": ["../../packages/**/*"],
36
+ }
37
+ ```
38
+
39
+ Then run:
40
+
41
+ ```bash
42
+ dotenv-diff
43
+ ```
44
+
45
+ ## `--include-files` vs `--files`
46
+
47
+ - `--include-files` **extends** default scan patterns
48
+ - `--files` **replaces** default scan patterns completely
49
+
50
+ For monorepos, `--include-files` is usually the best default because you keep built-in scanning and only add shared paths.
51
+
52
+ ## Why this matters in monorepos
53
+
54
+ - Undocumented variables are harder to detect when usage is spread across apps/packages
55
+ - Keeping `.env.example` accurate becomes harder as shared code grows
56
+ - One app-local scan can still include cross-folder usage and reduce drift
57
+
58
+ ## Best practices
59
+
60
+ - Run `dotenv-diff` from the app folder that owns the `.env` / `.env.example` pair
61
+ - Add shared package globs with `--include-files` (or `includeFiles` in config)
62
+ - Keep `ignore` small and explicit
63
+ - Use `--strict` in CI to fail fast on warnings and missing variables
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotenv-diff",
3
- "version": "2.6.1",
3
+ "version": "2.6.3",
4
4
  "type": "module",
5
5
  "description": "Detects environment variable issues, usage, and potential security risks.",
6
6
  "bin": {
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "files": [
19
19
  "dist/",
20
+ "docs/",
20
21
  "README.md",
21
22
  "CHANGELOG.md",
22
23
  "LICENSE"
@@ -68,19 +69,20 @@
68
69
  },
69
70
  "dependencies": {
70
71
  "chalk": "5.6.2",
71
- "commander": "^14.0.2",
72
+ "commander": "^14.0.3",
72
73
  "prompts": "^2.4.2"
73
74
  },
74
75
  "devDependencies": {
75
- "@release-it/conventional-changelog": "^10.0.4",
76
- "@types/node": "^25.0.9",
77
- "@typescript-eslint/eslint-plugin": "^8.53.1",
78
- "@typescript-eslint/parser": "^8.53.1",
76
+ "@release-it/conventional-changelog": "^10.0.5",
77
+ "@types/node": "^25.3.0",
78
+ "@types/prompts": "^2.4.9",
79
+ "@typescript-eslint/eslint-plugin": "^8.56.1",
80
+ "@typescript-eslint/parser": "^8.56.1",
79
81
  "@vitest/coverage-v8": "4.0.18",
80
- "eslint": "^9.39.2",
81
- "prettier": "^3.8.0",
82
+ "eslint": "^9.39.3",
83
+ "prettier": "^3.8.1",
82
84
  "release-it": "^19.2.4",
83
85
  "typescript": "^5.9.3",
84
- "vitest": "^4.0.17"
86
+ "vitest": "^4.0.18"
85
87
  }
86
88
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/ui/prompts.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACjE,OAAO,CAAC,OAAO,CAAC,CAclB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/ui/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,EAAE,QAAQ,EAAE,SAAS,EAA6C;IAElE,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;QACxB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,IAAI;QACV,OAAO;QACP,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;YAC7B,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;SAC9B;QACD,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
File without changes
File without changes