jcouture
nv
Go

CLI to load .env files, validate env schemas, and run commands with predictable environment variables

Last updated Jul 8, 2026
77
Stars
7
Forks
0
Issues
+1
Stars/day
Attention Score
56
Language breakdown
No language data available.
Files click to expand
README

nv

Release Software License Go Doc Go Report Card

nv runs any command with predictable environment variables from your .env files. Think “one-shot dotenv runner” for scripts, deploys, and local apps.

Quick start

Install

  • macOS (Homebrew):
brew install --cask jcouture/tap/nv
You may see a trust warning about jcouture/nv during install — this is a Homebrew alias and can be ignored; the cask itself is trusted. To silence future warnings, trust the tap explicitly:
brew trust jcouture/tap
  • Linux/Windows/macOS (binary): download the latest release from https://github.com/jcouture/nv/releases
To verify the release signature:
cosign verify-blob \
    --key https://raw.githubusercontent.com/jcouture/nv/main/cosign.pub \
    --bundle checksums.txt.sigstore.json \
    checksums.txt

Run a command with env vars

nv run -e .env -- ./myapp

nv loads the file(s) you point at and starts your command with those variables. Nothing is left running after the command exits.

Migrating from v2

The old tap (jcouture/nv) will not receive further updates. To upgrade:

brew uninstall --formula nv
brew untap jcouture/nv    # optional, avoids stale formula confusion
brew install --cask jcouture/tap/nv

If you want to stay on v2, no action is required. To block any future upgrades of the legacy formula, run brew pin nv.

v3 includes breaking changes. Review the release notes before upgrading.

Everyday moves

  • Cascade the usual dotenv chain: .env, .env.local, .env.<env>, .env.<env>.local
nv run --cascade --env=production -- ./deploy.sh

When you pass -e/--env-file, cascading turns off (with a warning) so only the files you listed are used.

  • Point at specific files (multiple allowed)
nv run -e .env -e .env.local -- ./myapp
  • Override inline for a one-off
nv run -e .env -o PORT=4200 -- ./myapp
  • Preview without running
nv run -e .env --dry-run -- ./myapp
  • Export for another tool
nv export -e .env --format=json
  • Validate before you run (defaults to .env.example as schema)
nv validate -e .env

Validation checks that your real .env has every required key and that required ones are non-empty. The schema file is just a list of keys with optional example values; it is not loaded at runtime. Schema example:

DATABASE_URL=postgres://localhost   # example value is ignored
  OPTIONAL=                           # empty value means "can be blank or missing"
  # REQUIRED: API_KEY                 # tag required keys with this comment
  • Use a custom schema file
nv validate -e .env --schema=.env.staging.example
  • See what is currently set
nv print --sort

Configuration (optional)

Config lives at ~/.config/nv/config.toml on Linux and macOS, and %APPDATA%\nv\config.toml on Windows. Run nv config path to see the exact location. If you still have a legacy ~/.nv file from v2, nv config migrate will import it and back up the original alongside the config file.

nv config init    # Create config with defaults
nv config show    # View your current config
nv config edit    # Edit config in $EDITOR

When nv run loads config, missing fields fall back to built-in defaults. Explicit values in config.toml, including false, 0, or empty strings, are treated as intentional settings and are not replaced.

Globals

Globals currently apply to nv run. nv export and nv validate currently use their own flags and built-in command defaults rather than loading globals.env from config.

nv config globals list
nv config globals set AWS_REGION us-east-1
nv config globals unset AWS_REGION

Priority at a glance

Default nv run order (highest first):

  • -o/--override KEY=value
  • .env.<env>.local (when cascading)
  • .env.<env> (when cascading)
  • .env.local (when cascading)
  • .env
  • [globals.env] when globals.priority = "first"
Set globals to load after files if you want them to win over .env values:
nv config set globals.priority "last"

.env syntax supported

  • KEY=value (with optional export)
  • # comments on their own line or inline (outside quotes)
  • Single- and double-quoted values with escapes, multiline inside quotes
  • Variable interpolation in unquoted and double-quoted values ($VAR, ${VAR})
  • PATH expansions preserve the incoming PATH

Troubleshooting

  • Permission denied on config
chmod 600 "$(nv config path)"
  • Config seems corrupted
nv config validate
  nv config reset
  • Restore backup
cp "$(dirname "$(nv config path)")/nv.backup" "$(nv config path)"

Build from source (latest dev)

  • Verify Go 1.26+
go version
  • Clone
git clone https://github.com/jcouture/nv.git
cd nv
mise install
  • Build
make build

License

nv is released under the MIT license. See LICENSE for details.

The nv leaf logo is based on this icon by Nick Bluth, from the Noun Project. Used under a Creative Commons BY 3.0 license.

🔗 More in this category

© 2026 GitRepoTrend · jcouture/nv · Updated daily from GitHub