DEV Community

Cover image for Managing and Securing Environment Variables (.env): A Look at evnx
Suchismita Moharana
Suchismita Moharana

Posted on

Managing and Securing Environment Variables (.env): A Look at evnx

As an AI security researcher, my work spans Python, Rust, and React - model training pipelines, experimental tooling, and small frontend interfaces. Like most developers, I rely on .env files for managing environment variables.

The problem shows up most clearly when sharing projects with lab members or pushing to an organization repository. A committed .env file, even accidentally, can expose API keys, database credentials, or model endpoint secrets. But beyond accidental commits, there's a quieter issue that comes up constantly in collaborative work: .env and .env.example falling out of sync.

After evaluating several tools in this space, I started using evnx, a recently released open-source CLI. This post covers practical use cases, installation, and how it compares to similar tools.


The .env / .env.example Sync Problem

Most projects maintain two files:

  • .env — the actual file with real credentials, never committed
  • .env.example — a template committed to the repository, with keys but no values

In practice, .env grows over time. New variables get added, some get removed, names change. The .env.example often doesn't keep up. A new collaborator clones the repo, copies .env.example to .env, and discovers that half the variables they actually need aren't listed or that some entries in .env.example no longer exist in the codebase.

The reverse is equally common: you're setting up a project from scratch and want to generate a working .env from .env.example, with safe placeholder values already filled in, so you have a complete starting point without hunting through documentation.

evnx addresses both directions explicitly.


What is evnx?

evnx is an open-source CLI written in Rust for initializing, syncing, validating, scanning, and converting .env files. It's a relatively new tool still in early versions, but already covers a solid range of the .env workflow.


Installation

evnx ships as a single static binary with no runtime dependencies.

macOS / Linux (recommended — consistent behavior across environments):

curl -fsSL https://dotenv.space/install.sh | bash
Enter fullscreen mode Exit fullscreen mode

This is the approach I use. It's the most straightforward and avoids environment-specific issues.

Cargo (Rust):

cargo install evnx
Enter fullscreen mode Exit fullscreen mode

pipx (preferred over pip):

pipx install evnx
Enter fullscreen mode Exit fullscreen mode

If you're in a Python environment, use pipx rather than pip install evnx. Installing CLI tools via pip into your active environment can create dependency conflicts and the tool may not be available globally. pipx installs it in an isolated environment and exposes on your PATH cleanly.

npm:

npm install -g evnx
Enter fullscreen mode Exit fullscreen mode

Full installation guide: evnx.dev/guides/getting-started/installation

evnx --version
# evnx 0.3.8
Enter fullscreen mode Exit fullscreen mode

Getting Started: Core Use Cases

1. Initializing a Project with evnx init

The first thing to do in a new project is set up the .env structure properly. Running evnx init creates both .env and .env.example, and adds .env to .gitignore automatically.

evnx init
Enter fullscreen mode Exit fullscreen mode

If you're starting a specific type of project, evnx has pre-built blueprints for common stacks:

evnx init --blueprint fastapi
evnx init --blueprint nextjs
evnx init --blueprint django
Enter fullscreen mode Exit fullscreen mode

These generate a .env.example pre-populated with the variables typical for that framework, a useful starting point rather than building from scratch.


2. Syncing .env and .env.example (Both Directions)

This is one of the more practical features and addresses the sync problem described above.

Forward sync — updating .env.example from .env:

When you've added new variables to your .env and want to propagate the keys (without values) to .env.example:

evnx sync --direction forward
Enter fullscreen mode Exit fullscreen mode

This keeps .env.example current with whatever is in your actual .env, replacing real values with safe placeholders. Useful before sharing a project or committing an updated template.

Reverse sync — generating .env from .env.example:

When a collaborator clones a repository and needs a working .env to start from:

evnx sync --direction reverse
Enter fullscreen mode Exit fullscreen mode

This creates a .env from .env.example with placeholder values filled in — CHANGE_ME, typed defaults, or inferred safe values — so there's a complete, valid file to edit rather than an empty starting point. No more manually copying the example file and hunting for what each variable should contain.

Both directions make the .env / .env.example relationship explicit and manageable, rather than something that drifts silently over time.


3. Scanning for Secrets

Once your project is set up, scanning is a quick check before any commit or share:

evnx scan
Enter fullscreen mode Exit fullscreen mode

evnx detects AWS keys, Stripe secrets, GitHub tokens, and high-entropy strings. For a specific path or output format:

evnx scan --path ./config --format sarif
Enter fullscreen mode Exit fullscreen mode

This can be integrated into a pre-commit hook so it runs automatically on every commit attempt, or used manually as a step before pushing or sharing a project:

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: evnx-scan
        name: Scan for secrets
        entry: evnx scan --exit-code
        language: system
        files: '\.env'
Enter fullscreen mode Exit fullscreen mode

4. Running a Health Check with evnx doctor

Before sharing a project with anyone, evnx doctor gives a full picture of the environment's state:

evnx doctor
Enter fullscreen mode Exit fullscreen mode

It checks whether .env is in .gitignore, whether file permissions are appropriate, whether .env.example is in sync, and flags anything that looks misconfigured. For a quick fix pass:

evnx doctor --fix
Enter fullscreen mode Exit fullscreen mode

This is a useful habit before handing off a project, three seconds to catch what's easy to miss.


Additional Features for Production and Enterprise Workflows

Beyond the core use cases above, evnx has several features worth knowing about for more complex setups:

Validation
Catches placeholder values (changeme, your-key-here), weak secrets, and localhost URLs in configs before deployment.

evnx validate --strict --exit-code
Enter fullscreen mode Exit fullscreen mode

Format Conversion (14+ targets)
Exports .env to Kubernetes Secrets, Terraform variables, GitHub Actions secrets, Doppler, Infisical, Vercel, Heroku, JSON, YAML, and more. Useful when the same variables must exist across multiple deployment formats.

evnx convert --from .env --to kubernetes
Enter fullscreen mode Exit fullscreen mode

Cloud Migration (Experimental)
Push secrets directly to AWS Secrets Manager, Doppler, Infisical, or GitHub Actions.

evnx migrate --to aws-secrets-manager
Enter fullscreen mode Exit fullscreen mode

Add Variables from CLI (New)
Manage .env entries without directly editing files.

evnx add DATABASE_URL "postgres://user:pass@localhost/db"
Enter fullscreen mode Exit fullscreen mode

Encrypted Backups
AES-256-GCM encryption with Argon2 key derivation for local backup storage.

Template Engine
Type filters (|int, |bool, |upper) for generating environment configs across multiple environments from a single template.

CI/CD Integration
SARIF output compatible with the GitHub Security tab. Exits 1 on findings for use as a pipeline gate in GitHub Actions, GitLab CI, or similar.


Comparison with Similar Tools

dotenv-vault

A cloud-based solution for encrypting and syncing .env files through a managed vault. Useful for team sharing, but requires an account and cloud dependency. No secret scanning, no format conversion, no CI gate functionality. evnx covers all of these and works entirely offline.

detect-secrets (Yelp)

A Python-based tool focused specifically on detecting credentials in source code. Single-purpose, no validation, sync, conversion, or diagnostics. A reasonable choice if scanning is all you need, but you'd still need other tooling for the rest of the .env lifecycle.

git-secrets (AWS Labs)

Prevents secret commits via configurable pattern scanning at the git hook level. Narrow in scope, requires manual per-repository configuration and has seen slow maintenance. evnx covers the same use case with less setup and adds considerably more.

Infisical CLI

A full secrets management platform with CLI support for runtime secret injection. Well-built for teams needing centralized secret storage, but requires an Infisical server or cloud account and a longer onboarding process. It's infrastructure, not a dev-time tool. evnx can migrate your .env files directly to Infisical if you decide to adopt it later.


Summary

evnx is a relatively new tool and is still adding features, but it already handles more of the .env workflow than any single alternative I've looked at initialization, bidirectional sync, scanning, validation, format conversion, and health diagnostics without requiring accounts, cloud dependencies, or a complex setup.

For research environments where projects move between local machines, shared lab systems, and organizational repositories, it's a practical addition to the workflow. The sync functionality alone, both directions, solves a problem that most .env tooling doesn't address at all.

Worth trying: evnx.dev

curl -fsSL https://dotenv.space/install.sh | bash
evnx doctor
Enter fullscreen mode Exit fullscreen mode

Top comments (0)