Inspiration

I kept running into huge .env and .env.local files across my projects. Variables would be added in code but never documented, old variables stayed for months because deleting them felt risky and configuration mistakes appeared only after deployment. Some variables also belonged to external providers such as Convex, so a strict "everything must be local" rule would create noise.

I wanted environment configuration to behave like a real contract: code should say what it needs, a schema should explain what is allowed and CI should catch drift before production does.

What it does

MyEnv is a Go CLI that cross-references three sources of truth:

  1. JavaScript/TypeScript code using process.env or import.meta.env.
  2. A committed .myenv.yaml schema.
  3. A dotenv file or encrypted dotenv payload.

It can generate a starter schema, validate required values, types, ranges, and regex patterns, find code variables missing from schema, find stale config, flag browser exposure of marked secrets, and warn about likely secrets in Git-tracked .env* files.

myenv can also gzip-compress and AES-256-GCM encrypt dotenv bytes into .myenv.yaml. GitHub Actions can use MYENV_DECRYPT_KEY to decrypt in memory and validate real values without committing a plaintext .env file.

How we built it

We built myenv as a Go CLI with a small, testable internal architecture:

  • YAML schema parser and rule normalizer.
  • Pure dotenv validation functions.
  • Static JS/TS scanner with file and line diagnostics.
  • Diff layer for code, dotenv, and schema comparisons.
  • Explicit ignore policy inside .myenv.yaml.
  • AES-256-GCM encryption package with gzip compression.
  • GitHub Action wrapper around myenv ci.
  • NPM launcher and prebuilt binaries for Windows, macOS, and Linux.

Codex was the main part of the full workflow: architecture first, then implementation, tests, CLI UX, encryption, CI, package distribution, demo fixtures and docs.

Challenges we ran into

Real projects do not have perfectly static configuration. Generated Nuxt files, dynamic environment access, provider-managed values and deployment-only settings can all look like errors to a scanner. We had to keep checks useful without making them noisy.

We solved this with narrow ignore controls for paths, rule IDs, code variables, and intentionally unused configuration. The default remains strict, but users can document why a specific exception exists.

Encryption created another challenge: deleting a temporary dotenv file is not enough security. The CI command now decrypts only in memory, never prints keys or plaintext values, and still performs code/schema checks when GitHub Secrets are unavailable for fork pull requests.

Accomplishments that we're proud of

  • Built a working cross-reference tool, not only a schema validator.
  • Made diagnostics actionable with exact source locations, severity colors, and plain-language pattern hints.
  • Added schema synchronization that preserves existing rule settings.
  • Added encrypted dotenv validation in GitHub Actions without plaintext files.
  • Added passing and intentionally failing CI fixtures so judges can test the product quickly.
  • Published an NPM launcher so users can install once and run myenv globally.
  • Kept the product local-first: no hosted dashboard or secrets service needed.

What we learned

Environment configuration is part of an application's API surface, not just a deployment detail. The useful product is the relationship between code, documentation, and values.

We also learned that developer tools need trust as much as detection quality: clear error messages, safe defaults, stable exit codes, focused ignore rules, and secure CI behavior decide whether teams will keep using the tool.

Codex made iterative product engineering much faster. It helped move from a problem statement to architecture, testable implementation, distribution, and real demo workflows while keeping decisions visible in the repository.

What's next for MyEnv

  • Add Go, Python and more framework-aware source scanners.
  • Add Git history scanning for secrets that were committed previously.
  • Add release automation, signed binaries and package provenance.
  • Improve schema inference with optional interactive rule suggestions.
  • Add team policy packs for common platforms and deployment providers.
  • Keep the core product local-first, transparent and CI-friendly.

Built With

Share this project:

Updates