npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@akshxy/envgit

v0.6.2

Published

Encrypted per-project environment variable manager

Downloads

1,270

Readme

envgit

Encrypted per-project environment variable manager. Commit your secrets safely — encrypted at rest, decrypted only on machines that have the key.

npm install -g @akshxy/envgit

Why

.env files get committed by accident. Sharing secrets over Slack or email is a disaster waiting to happen. envgit fixes both:

  • Secrets are encrypted with AES-256-GCM and live in .envgit/ — safe to commit
  • The key lives on your machine only (~/.config/envgit/keys/) — never touches the repo
  • Onboard a teammate: envgit share → copy the output → send via Signal/iMessage → they run envgit join
  • envgit unpack writes a clean, beautifully formatted .env grouped by service

Quick start

# 1. Initialize in your project
envgit init

# 2. Set variables
envgit set API_KEY=abc123 DB_URL=postgres://localhost/mydb

# 3. Or load from an existing .env file
envgit set -f .env.local

# 4. Commit the encrypted store — key never included
git add .envgit/
git commit -m "chore: add encrypted env"

# 5. Switch env and write .env locally
envgit use dev
envgit unpack

Team workflow

# ── Developer A (project owner) ──────────────────────────
envgit init
envgit set DB_URL=postgres://... OPENAI_API_KEY=sk-...
git add .envgit/ && git commit -m "chore: encrypted env"

envgit share
# ✓ Key encrypted. Send the command below to your teammate via Signal, iMessage, email — anywhere.
#
#   envgit join <blob> --code <passphrase>
#
# Copy that one line and send it. Nothing was uploaded anywhere.

# ── Developer B (teammate, after cloning) ─────────────────
envgit join <blob> --code <passphrase>
# ✓ Key saved to ~/.config/envgit/keys/<project-id>.key

envgit verify        # confirm the key works
envgit unpack        # writes .env (picks up active env)

No server involved. The blob is AES-256-GCM encrypted — useless without the passphrase. Send both parts via any channel you trust.


Formatted .env output

When you run envgit unpack, the .env is written with sections grouped by service — no more chaotic unsorted files:

# ──────────────────────────────────────────────────
#  envgit — encrypted environment manager
#  Project : myapp
#  Env     : dev
#  Edit    : envgit set KEY=VALUE --env dev
# ──────────────────────────────────────────────────

# ── App / Config ────────────────────────────────
NODE_ENV=development
PORT=3000

# ── AI / Anthropic ──────────────────────────────
ANTHROPIC_API_KEY=sk-ant-...

# ── AI / OpenAI ─────────────────────────────────
OPENAI_API_KEY=sk-...

# ── Auth / Clerk ────────────────────────────────
CLERK_SECRET_KEY=sk_test_...

# ── Auth / NextAuth ─────────────────────────────
NEXTAUTH_SECRET=...
NEXTAUTH_URL=http://localhost:3000

# ── AWS ─────────────────────────────────────────
AWS_ACCESS_KEY_ID=AKIA...
AWS_REGION=us-east-1
AWS_SECRET_ACCESS_KEY=...

# ── Cache / Redis ───────────────────────────────
REDIS_URL=redis://localhost:6379

# ── Database / PostgreSQL ───────────────────────
DATABASE_URL=postgres://localhost/mydb

# ── Next.js / Public (client-side) ──────────────
NEXT_PUBLIC_API_URL=http://localhost:3000/api

# ── Payments / Stripe ───────────────────────────
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...

# ── Supabase ────────────────────────────────────
SUPABASE_ANON_KEY=eyJ...
SUPABASE_URL=https://xyz.supabase.co

Supports 100+ services out of the box: OpenAI, Anthropic, Groq, Stripe, Supabase, Clerk, Auth0, NextAuth, AWS, GCP, Azure, Redis, Upstash, Resend, SendGrid, Twilio, Sentry, Datadog, PostHog, Segment, Algolia, Pinecone, Cloudinary, and many more.


Commands

Key management

| Command | Description | |---------|-------------| | envgit init | Initialize project, generate key, save to ~/.config/envgit/keys/ | | envgit share | Encrypt key locally, print a blob + passphrase to send to a teammate | | envgit join <blob> --code <passphrase> | Save a key from envgit share output | | envgit rotate-key | Generate new key and re-encrypt all environments, then run envgit share | | envgit verify | Confirm all environments decrypt with the current key |

Variables

All variable commands are interactive — run them without arguments to get a fuzzy search picker.

| Command | Description | |---------|-------------| | envgit set KEY=VALUE ... | Set one or more variables | | envgit set -f .env | Import all variables from a .env file | | envgit set -f .env --env prod | Import into a specific environment | | envgit get KEY | Print a single value | | envgit delete KEY | Remove a variable | | envgit rename OLD NEW | Rename a variable | | envgit copy KEY --from dev --to prod | Copy a variable between environments | | envgit list | List all keys in the active environment | | envgit list --show-values | List keys and their values |

Environments

| Command | Description | |---------|-------------| | envgit envs | List all environments with variable counts | | envgit use <env> | Switch active environment (like git checkout) | | envgit add-env <name> | Create a new environment | | envgit unpack [env] | Decrypt and write a formatted .env file | | envgit diff dev prod | Show what's different between two environments | | envgit diff dev prod --show-values | Include values in the diff |

Export & run

| Command | Description | |---------|-------------| | envgit export | Print KEY=VALUE lines to stdout (pipeable) | | envgit export --format json | Print as JSON | | envgit export --format shell | Print as export KEY="VALUE" (eval-able) | | envgit export --env prod | Export a specific environment | | envgit run -- node server.js | Run a command with env vars injected, nothing written to disk | | envgit import --file .env.local | Encrypt an existing .env file |

Utilities

| Command | Description | |---------|-------------| | envgit status | Show project root, active env, key location, .env state | | envgit doctor | Check everything — key, envs, git safety — in one shot | | envgit audit | Show which keys are missing across environments | | envgit scan | Scan codebase for hardcoded secrets using patterns and entropy analysis | | envgit template | Generate a .env.example with all keys, no values | | envgit fix | Post-upgrade repair: migrate config, fix permissions, update .gitignore |


--env flag

Most commands default to the active environment. Pass --env to target any environment explicitly:

envgit set STRIPE_KEY=sk_live_... --env prod
envgit list --env staging
envgit export --env prod --format json | jq .
envgit run --env prod -- node scripts/migrate.js

CI / CD

Set ENVGIT_KEY instead of using a key file:

# GitHub Actions
- name: Decrypt env
  env:
    ENVGIT_KEY: ${{ secrets.ENVGIT_KEY }}
  run: envgit export --env prod --format shell >> $GITHUB_ENV
# Local one-liner
ENVGIT_KEY=$(cat ~/.config/envgit/keys/<id>.key) envgit run -- node server.js

Security

  • AES-256-GCM — authenticated encryption, any tampering is detected
  • 32 bytes of entropy from the OS cryptographic RNG (crypto.randomBytes)
  • Fresh random IV per write — encrypting the same value twice produces different ciphertext
  • Key stored at ~/.config/envgit/keys/ — never in the repo, never in .env
  • File permissions enforced — key files are locked to 0600, errors if too permissive
  • Key bytes zeroized from memory immediately after use
  • No plaintext ever written except when you explicitly run envgit unpack
  • No serverenvgit share encrypts your key locally with a one-time passphrase. Nothing is uploaded anywhere. You send the blob yourself via any channel you trust.

Threat model

What envgit protects against

| Threat | Protection | |--------|-----------| | .env accidentally committed to git | Encrypted files are safe to commit — plaintext never touches the repo | | Secrets shared over Slack, email, chat | envgit share outputs an AES-256-GCM blob — useless without the passphrase. Send both parts, split across channels if paranoid. | | Teammate's machine is compromised | Key is per-machine — compromise one machine, not all | | Secrets hardcoded in source | envgit scan detects these using pattern matching and entropy analysis |

What envgit does NOT protect against

  • A compromised machine where the key file is readable — if your machine is owned, the key is accessible
  • Secrets that have already been committed in plaintext to git history — use git filter-repo to scrub those
  • An attacker who intercepts both the relay token AND the passphrase at the same time — treat the passphrase like a password

How it works

Your machine                                         Teammate's machine
────────────────                                     ──────────────────────

project.key (32 bytes)
    │
    ▼
encrypt with
one-time passphrase
    │
    ▼
envgit share prints:
  envgit join <blob> --code <passphrase>
    │
    │   ← you send this line via Signal, iMessage, email, etc. →
    │
    ▼                                                envgit join <blob> --code <passphrase>
                                                         │
                                                         ▼
                                                     decrypt blob with passphrase
                                                         │
                                                         ▼
                                                     key saved to
                                                     ~/.config/envgit/keys/

No server. No upload. The blob is AES-256-GCM encrypted — without the passphrase it is indistinguishable from random noise.


Crypto decisions

Why AES-256-GCM? GCM is an authenticated encryption mode — it detects tampering. If anyone modifies the ciphertext (even one byte), decryption fails loudly rather than silently returning corrupt data. This matters for secrets: you want to know immediately if something has been tampered with.

Why 32 bytes of entropy? NIST recommends 128-bit minimum for symmetric keys. envgit uses 256-bit (32 bytes) from crypto.randomBytes, which reads from the OS CSPRNG. This is the same source used by OpenSSL and Node's TLS stack.

Why a fresh IV per write? AES-GCM requires a unique IV per (key, message) pair. Reusing an IV with the same key catastrophically breaks confidentiality — an attacker can XOR two ciphertexts to cancel out the keystream. envgit generates a new random IV on every write, making this impossible.

Why zeroize key bytes after use? Node.js buffers live in V8's heap. Without explicit zeroization, key bytes can persist in memory until GC runs — and could potentially be read from a core dump or swap file. envgit calls buffer.fill(0) immediately after the crypto operation completes.