@amtstack/envmaster
v0.1.4
Published
The ultimate environment variable discovery, generation, validation, synchronization, and management toolkit for modern JavaScript applications.
Maintainers
Readme
EnvMaster is a next-generation CLI and SDK that statically analyzes your codebase to find exactly what environment variables are required, automatically generates and synchronizes .env.example files, validates your local .env, and audits your secrets for security vulnerabilities.
Unlike traditional tools that rely on fragile and error-prone regular expressions, EnvMaster parses your code into Abstract Syntax Trees (ASTs) using Babel. This means it understands your code exactly like a compiler does, guaranteeing 100% accuracy even in complex nested structures, destructuring patterns, and dynamic setups.
✨ Key Features
- 🔍 AST-Powered Scanning: Intelligently and reliably finds
process.env.Xandimport.meta.env.Xusage across JavaScript, TypeScript, JSX, and TSX files. - 🏗️ Smart Generator: Creates beautiful
.env.examplefiles. It automatically categorizes variables, adds context-aware comments, and preserves your custom dummy values. - ✅ Strict Validation: Instantly flags missing variables by comparing your local
.envfile directly to your actual codebase usage. Never deploy broken code again. - 🛡️ Security Analyzer: Scans your local
.envfor weak secrets, placeholder strings, and accidentally exposed private keys (like PEM headers or base64 keys). - 🔌 Auto-Detect Plugins: 11 built-in presets for frameworks and services (Prisma, NextAuth, Stripe, PostgreSQL, MongoDB, Redis, etc.) that automatically validate formats and API keys.
- 👁️ Watch Mode (
chokidar): A background daemon that updates your.env.examplein real-time as you code. - 🤖 CI/CD Integration: Strict pipeline validation that natively outputs GitHub Action annotations on PRs for missing variables.
- 📦 Monorepo Ready: Detects Turborepo, Nx, and standard workspaces (npm, yarn, pnpm, lerna) out of the box.
- 🔀 Universal Exporters: Export your environment into JSON, YAML, or TOML programmatically.
🚀 Installation & Quick Start
You can use EnvMaster instantly via npx without installing it:
# Run a comprehensive health check on your project
npx @amtstack/envmaster doctor
# Generate an accurate .env.example file based on your code
npx @amtstack/envmaster generate
# Validate your local .env against the codebase requirements
npx @amtstack/envmaster validateIf you prefer to install it locally in your project:
npm install --save-dev @amtstack/envmaster
# or
yarn add -D @amtstack/envmaster
# or
pnpm add -D @amtstack/envmasterOnce installed, you can initialize a config file and add scripts to your package.json:
{
"scripts": {
"env:check": "envmaster validate",
"env:sync": "envmaster sync",
"env:watch": "envmaster watch"
}
}💻 CLI Commands Reference
envmaster init
Initializes a new envmaster.config.ts (or .js) configuration file in your project root with sensible, framework-detected defaults.
envmaster doctor
Runs a comprehensive project audit. It detects your framework, scans the codebase for environment variable usage, validates your local .env against those variables, detects unused environment variables, and performs a deep security analysis on your secrets.
Options:
--root <dir>: Specify the root directory to run the doctor check on (default: current directory).--json: Output the entire report in JSON format for programmatic ingestion.--verbose: Enable detailed log output.
Sample Output:
🌌 EnvMaster Doctor - Project Audit
-------------------------------------
✓ Framework Detected: Next.js
✓ Codebase Scanned: 42 files found with 18 environment variables.
Validation Report:
✗ API_KEY is missing from .env
✓ DATABASE_URL is present and valid
Security Audit:
⚠ STRIPE_SECRET_KEY is too short (< 16 chars)
⚠ GOOGLE_CLIENT_SECRET contains placeholder value ("your-secret-here")
Recommendations:
- Add API_KEY to your local .env file.
- Update GOOGLE_CLIENT_SECRET with a real secret value.envmaster generate (alias g)
Scans your entire codebase and generates a fresh .env.example file. It groups variables logically by category (e.g. database, auth, frameworks) and preserves existing dummy values if the file already exists.
Options:
-o, --output <path>: Custom output file path (default:.env.example).-f, --force: Overwrite the existing file entirely instead of preserving values.--no-sort: Disable alphabetical sorting of variables.--no-group: Disable category-based grouping.
envmaster validate
Compares your local .env file against the variables actually found in your source code. It fails with a non-zero exit code (exit 1) if required variables are missing, ensuring you never push broken code to production.
Options:
-e, --env-file <path>: Path to a specific.envfile to validate (default:.env).--strict: Fail the command even if there are only warnings (e.g., security warnings or plugin format warnings).
envmaster sync (alias s)
Safely updates your .env.example file based on a fresh codebase scan. Unlike generate, it only adds newly discovered variables and guarantees it will never overwrite your existing values, custom placeholders, or comments.
envmaster watch (alias w)
Starts a persistent background watcher using chokidar. As you write code and add new environment variables, EnvMaster automatically detects them and syncs them to your .env.example in real-time.
envmaster compare
Visualizes the differences between multiple environment files (e.g., .env vs .env.production vs .env.example) using a clean matrix in the terminal.
Options:
-f, --files <paths>: Comma-separated paths to the files to compare.
Usage:
npx envmaster compare --files .env,.env.example,.env.productionenvmaster ci
Designed specifically for CI/CD pipelines. It runs in strict mode, disables interactive elements (spinners and colors if colors are not supported), and generates machine-readable output or PR annotations if a variable is missing.
⚙️ Configuration Reference
Customize EnvMaster by creating an envmaster.config.ts (or .js, .json) file. You can import the defineConfig helper to get complete autocompletion and type-safety:
import { defineConfig } from '@amtstack/envmaster';
export default defineConfig({
// Directories or files to ignore during the AST scan
ignore: ['**/*.test.ts', '**/*.spec.ts', 'dist/**', 'node_modules/**'],
// Output path for generate/sync commands
output: '.env.example',
// File extensions to scan
extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'],
// Scan mode: 'ast' (highly accurate), 'regex' (fastest), or 'hybrid' (uses both)
scanMode: 'hybrid',
// Files to consider during validation / comparison
envFiles: ['.env', '.env.local', '.env.development'],
security: {
enabled: true,
minSecretLength: 16,
detectWeakSecrets: true,
detectPlaceholders: true, // Flags "your-api-key-here" or "TODO"
detectExposedKeys: true, // Flags PEM headers and raw private keys
secretPatterns: ['API_KEY', 'SECRET', 'TOKEN', 'PASSWORD'],
},
ci: {
enabled: false, // Auto-enabled when using `envmaster ci`
platform: 'auto', // 'github-actions' | 'gitlab-ci' | 'jenkins' | 'circleci' | 'azure-devops' | 'auto'
failOnWarnings: true,
outputFormat: 'annotations',
}
});Configuration Options
| Property | Type | Default | Description |
|---|---|---|---|
| ignore | string[] | ['**/node_modules/**', '**/dist/**', '**/.git/**'] | Glob patterns to ignore during scanning |
| output | string | '.env.example' | Output path for the generated/synced example file |
| extensions | string[] | ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'] | File extensions to parse |
| scanMode | 'ast' \| 'regex' \| 'hybrid' | 'hybrid' | Engine mode to use for environment variable discovery |
| sortVariables | boolean | true | Sort variables alphabetically |
| groupByCategory| boolean | true | Group variables into sections with comment headers |
| detectUnused | boolean | true | Flag variables declared in env files but never used in code |
| envFiles | string[] | ['.env'] | Env files to load for validation and comparing |
| security | SecurityConfig | (Strict rules enabled) | Settings for local security audits |
| ci | CIConfig | (Platform-aware config) | Config for CI pipeline running |
🔌 Plugin System & Presets
EnvMaster automatically detects which services and frameworks your project uses by analyzing your package.json dependencies and root configuration files. It then applies specific validation rules and auto-injects required variable definitions.
Built-in Presets
EnvMaster comes with 11 built-in plugins out of the box:
- Frameworks: Next.js, Vite, Nuxt, Astro, SvelteKit, Remix, Express.
- Databases: Prisma (
DATABASE_URL), PostgreSQL, MySQL, MongoDB, Redis. - Authentication: NextAuth.js (
NEXTAUTH_URL,NEXTAUTH_SECRET), Supabase, Firebase, Clerk. - Third-Party Services: Stripe (
STRIPE_SECRET_KEY), Resend.
Example: If stripe is found in your package.json dependencies, EnvMaster will automatically validate that your STRIPE_SECRET_KEY actually begins with the sk_ prefix in your .env.
Writing Custom Plugins
You can write your own plugins and inject them via the configuration file or the programmatic API. Custom plugins allow you to enforce rules specific to your internal company infrastructure:
import { defineConfig } from '@amtstack/envmaster';
import type { EnvMasterPlugin } from '@amtstack/envmaster';
const companyApiPlugin: EnvMasterPlugin = {
name: 'my-company-api',
version: '1.0.0',
variables: [
{ name: 'COMPANY_API_URL', required: true, validation: 'url', category: 'Third Party' },
{ name: 'COMPANY_API_TOKEN', required: true, category: 'Third Party' }
],
detect: (context) => {
// Enable this plugin if the corporate API SDK is installed
return !!context.packageJson?.dependencies?.['@mycompany/api-sdk'];
},
validate: (context, envValues) => {
const results = [];
if (envValues.COMPANY_API_TOKEN) {
if (!envValues.COMPANY_API_TOKEN.startsWith('co_')) {
results.push({
variable: 'COMPANY_API_TOKEN',
status: 'fail',
message: 'Company API token must start with prefix "co_"',
plugin: 'my-company-api'
});
}
}
return results;
}
};
export default defineConfig({
plugins: [companyApiPlugin]
});📦 Monorepo Integration
EnvMaster natively understands and resolves monorepos. It automatically detects configurations from:
- Turborepo (
turbo.json) - Nx (
nx.json) - Lerna (
lerna.json) - Workspaces (npm, pnpm, yarn workspaces)
When running inside a monorepo root, EnvMaster resolves all packages and allows you to either output a combined workspace report or run isolated env validations per package, ensuring that your microservices maintain independent .env.example definitions flawlessly.
export default defineConfig({
monorepo: {
enabled: true,
type: 'auto', // Autodetects Turborepo, Nx, pnpm, etc.
perPackage: true, // Generates a separate .env.example inside each workspace package
rootReport: true, // Generates a consolidated check report at the root level
packages: [] // Specific workspaces to target (leave empty for all)
}
});🤖 CI/CD Orchestration
You can integrate EnvMaster into your CI pipeline to block pull requests that introduce new environment variables without updating .env.example, or to verify production environments contain all required keys.
GitHub Actions Integration
Add the following step to your .github/workflows/ci.yml. Because EnvMaster natively detects GitHub Actions, it automatically formats errors as workflow annotations:
name: CI
on:
pull_request:
branches: [ main, master ]
jobs:
validate-env:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Verify Environment Variables
run: npx @amtstack/envmaster ciGitLab CI Integration
validate_env:
stage: test
image: node:20
script:
- npm ci
- npx @amtstack/envmaster ci🔀 Programmatic API
EnvMaster exposes its underlying engines for use in custom scripts, build tools, or server side processes.
import { scan, validate, parseEnvFile, exportEnv } from '@amtstack/envmaster';
async function runCustomTool() {
// 1. Scan the project files for environment variables
const scanResult = await scan({
rootDir: process.cwd(),
scanMode: 'ast'
});
console.log(`Found ${scanResult.variables.length} environment variables.`);
// 2. Parse a local env file
const envFile = await parseEnvFile('.env');
// 3. Programmatically export env values into JSON, YAML, or TOML
await exportEnv(envFile, 'json', './dist/config.json');
await exportEnv(envFile, 'yaml', './dist/config.yaml');
await exportEnv(envFile, 'toml', './dist/config.toml');
// 4. Validate the env values against scanned variables
const validationReport = await validate(scanResult.variables, envFile.variables);
console.log(`Passed: ${validationReport.passed}, Failed: ${validationReport.failed}`);
}
runCustomTool();🛡️ Security Audit Rules
When running envmaster doctor or when security.enabled is set to true, your env files are audited against these default rules:
- Length Check: Any key matched as a secret (containing
API_KEY,SECRET,TOKEN,PASSWORDetc.) must be at least 16 characters long. - Entropy & Weak Secrets: Flags common values like
123456,password,secret,admin, or keys matching the variable name. - Placeholder Check: Detects common placeholder text such as
your-key-here,TODO,xxx,<insert-here>. - Accidental Exposure Check: Flags files containing private key headers (such as
-----BEGIN PRIVATE KEY-----) or long un-hashed keys that might have been copied by mistake.
📄 License & Attribution
EnvMaster is open-source software licensed under the MIT License.
Developed with ❤️ by Abdullah Al Mubin at AmtStack.
