beginner5 minutesevnx v0.2.1+

evnx sync

Reference documentation for the evnx sync command: bidirectional sync, smart placeholders, and security features.

Prerequisites

evnx sync — Command Reference

Keep .env and .env.example in perfect synchronization with bidirectional sync, smart placeholder generation, and built-in security guards.

Before you start

Security Notice: The "add with actual values" option in forward sync can expose secrets if .env.example is committed to version control. This option:

  • Shows an explicit warning prompt before proceeding
  • Is automatically disabled when --force is used in CI environments
  • Logs a security audit message when selected

Always prefer placeholder values for template files.


Command signature

Bash
evnx sync [OPTIONS]

Options reference

FlagTypeDefaultDescription
--direction, -denumforwardSync direction: forward (.env.env.example) or reverse (.env.example.env)
--placeholder, -pboolfalseUse placeholder values when adding new variables (ignored in --force mode, which always uses placeholders for safety)
--dry-run, -nboolfalsePreview changes without writing to files
--force, -fboolfalseSkip interactive prompts; auto-use placeholders (safe for CI/CD)
--template-configpathPath to custom placeholder JSON config for regex-based pattern matching
--naming-policyenumwarnHandle non-standard variable names: warn, error, or ignore
--verbose, -vboolfalseEnable detailed debug output
--help, -hboolfalseDisplay help information

Direction values

ValueFlowUse case
forward.env.env.exampleUpdate team template with new variables from your local environment
reverse.env.example.envPull new variables from team template to your local environment

Naming policy values

PolicyBehaviorBest for
warnShows warning for non-UPPERCASE_WITH_UNDERSCORES names, continuesLocal development (default)
errorFails immediately on non-standard namesCI/CD validation, strict teams
ignoreNo validation, silentLegacy projects with unconventional naming

Placeholder generation rules

When adding variables with placeholders, evnx uses these built-in heuristics (customizable via --template-config):

Variable patternGenerated placeholder
Contains SECRET, KEY, or TOKENYOUR_KEY_HERE
Contains PASSWORD or PASSYOUR_PASSWORD_HERE
Contains URL + value starts with postgresql://postgresql://user:password@localhost:5432/dbname
Contains URL + value starts with redis://redis://localhost:6379/0
Contains URL + value starts with http(s)://https://your-api-url-here.com
Contains URL (other)YOUR_URL_HERE
Contains PORT8000
Contains DEBUGtrue
Contains HOST or SERVERlocalhost
UnmatchedYOUR_VALUE_HERE (or custom default from config)

Exit codes

CodeMeaningUse case
0✅ Sync completed successfullySuccess in scripts/CI
1🚨 Sync failed (missing files, validation errors, user abort)Fail pipeline on issues
2+⚠️ Runtime errors (IO failures, parsing errors, permission issues)Debug tooling or environment issues

Basic usage examples

Forward sync (default)

Bash
# Update .env.example with new variables from .env
# Interactive: choose placeholder vs actual values
evnx sync

Reverse sync

Bash
# Pull new variables from .env.example to .env
# Interactive: choose placeholder vs prompt for real values
evnx sync --direction reverse

Preview without changes

Bash
# See what would change before applying
# Shows 🔒 for placeholders, ⚠️ for actual values
evnx sync --dry-run

CI/CD mode (safe defaults)

Bash
# Skip prompts, always use placeholders, fail on naming issues
# Actual values option is disabled for security
evnx sync --force --naming-policy error

Custom placeholder config

Bash
# Use team-specific placeholder patterns with regex
# Example placeholders.json:
# {
#   "patterns": {
#     "AWS_.*": "aws_placeholder",
#     "STRIPE_.*": "sk_test_xxx"
#   },
#   "default": "TEAM_DEFAULT_VALUE"
# }
evnx sync --template-config .evnx/placeholders.json

Strict naming validation

Bash
# Fail if any variable doesn't match UPPERCASE_WITH_UNDERSCORES
evnx sync --naming-policy error

Interactive mode behavior

Forward sync prompts

When new variables are found in .env but not .env.example:

┌─ Variables to Add ─────────────────────────────────────┐
│ Found 2 variable(s) in .env missing from .env.example:│
│   • NEW_API_KEY                                       │
│   • DATABASE_URL                                      │
└────────────────────────────────────────────────────────┘

Add these to .env.example?
❯ Yes, add with placeholder values (recommended)
  Yes, add with actual values ⚠️ SECURITY RISK
  Let me choose individually
  No, skip

Reverse sync prompts

When new variables are found in .env.example but not .env:

┌─ Missing Variables ────────────────────────────────────┐
│ Found 2 variable(s) in .env.example missing from .env:│
│   • NEW_FEATURE_FLAG                                  │
│   • OPTIONAL_CONFIG                                   │
└────────────────────────────────────────────────────────┘

Add to .env?
❯ Yes, with placeholder values
  Yes, prompt me for real values
  Let me choose individually
  No, skip

Security features

File permissions check

On Unix systems, evnx warns if .env has overly permissive permissions:

⚠️ .env has permissive permissions (0o664). Consider: chmod 600 .env
ℹ️ Overly permissive .env files may expose secrets to other users

Recommendation: Always use chmod 600 .env to restrict access to owner only.

Atomic file writes

All file modifications use atomic write operations:

  1. Write to temporary file in same directory
  2. Sync to disk with fsync
  3. Atomic rename to target path

This prevents file corruption from interrupted operations or power loss.

Force mode safety

When --force is used:

  • Interactive prompts are skipped entirely
  • Placeholder values are always used (actual values option disabled)
  • Suitable for CI/CD pipelines where non-interactive execution is required

Audit logging

When actual values are added to .env.example (interactive mode only), a security audit message is logged to stderr in verbose mode:

[AUDIT] User added actual values to .env.example for keys: ["SECRET_KEY", "API_TOKEN"]

Environment variables

VariableValuesDefaultDescription
NO_COLOR1, truefalseDisable colored output for terminals or log files
CI1, truefalseAuto-enable non-interactive mode (equivalent to --force)

Troubleshooting

".env file not found" error

✗ File not found: .env

┌─ 💡 Getting Started ─────────────────────────────────┐
│ It looks like this project hasn't been initialized   │
│ yet. To create .env and .env.example files, run:     │
│                                                      │
│ $ evnx init                                          │
└──────────────────────────────────────────────────────┘

Solution: Run evnx init to create template files, or copy your existing .env to the project directory.

".env.example not found" in reverse sync

✗ File not found: .env.example

┌─ 💡 Getting Started ─────────────────────────────────┐
│ The template file .env.example is missing.           │
│ To create it, either:                                │
│ 1. Run 'evnx init' to generate from a blueprint, OR │
│ 2. Create .env.example manually with your variables │
└──────────────────────────────────────────────────────┘

Solution: Run evnx init or create .env.example manually with variable names (values can be placeholders).

Non-standard variable name warnings

⚠️ Variable 'myCamelCaseVar' doesn't follow convention (UPPERCASE_WITH_UNDERSCORES)

Solution: Rename to MY_CAMEL_CASE_VAR, or use --naming-policy ignore for legacy projects.

Placeholder not matching expected pattern

If a variable like DATABASE_URL gets YOUR_URL_HERE instead of a PostgreSQL template:

Check: The original value in .env must start with postgresql:// (not just postgres://) to trigger the specialized template.

Fix: Update the value format, or use --template-config to define custom patterns:

JSON
{
  "patterns": {
    "DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb"
  }
}

See also