Skip to content

Repository files navigation

@envify/cli

Keep .env files validated and in sync across your team — without updating docs every time a key changes.


The problem

Every project uses .env files. Every team has the same friction:

  • New developer joins → nobody knows which keys are required
  • Someone adds STRIPE_WEBHOOK_SECRET → half the team breaks silently
  • Docs go stale within a week
  • Copy-pasting values over Slack/Notion is error-prone and insecure

Envify solves this by making your schema the source of truth and syncing shared values through an encrypted remote store.


How it works

.envsync.yml → defines your schema (required keys, types, scope)
.env.shared → team values (synced via remote, encrypted)
.env.local → personal overrides (never synced, never pushed)
~/.envify/<proj>.key → your encryption key (never in the repo)

Keys marked scope: shared are pushed/pulled to the remote. Keys marked scope: personal are validated locally but never leave your machine.


Installation

From source

git clone https://github.com/your-org/envify.git
cd envify/sdk-node
npm install
npm run build
npm link

Requirements

  • Node.js >= 20.0.0
  • pnpm >= 9

Quick start

1. Initialize a project

# Generate a new key and scaffold .envsync.yml
envsync init --project my-app
# Or import an existing team keyprintf"%s""<hex-key>"| envsync init --stdin-key --project my-app

2. Edit your schema

# .envsync.ymlproject: my-appkeyfile: autofiles:
- path: .env.sharedschema:
PORT:
required: truetype: intdefault: 3000scope: sharedNODE_ENV:
required: truetype: enumallowed: [development, test, production]scope: sharedAPI_URL:
required: truetype: stringscope: sharedAPI_KEY:
required: truetype: stringscope: sharedsecret: trueDEV_SERVER:
required: falsetype: stringscope: personalremote:
type: filepath: .envsync-remote

3. Validate

envsync check
# ✔ .env.shared — all variables are valid

4. Push to remote

envsync push
# ✔ Encrypted and pushed 1 file(s) to remote

5. Pull on another machine

printf"%s""<hex-key>"| envsync init --stdin-key --project my-app
envsync pull
# ✔ Updated .env.shared# ✔ Pulled and decrypted 1 file(s) from remote

6. See what changed

envsync diff
# + STRIPE_WEBHOOK_SECRET=...# ~ API_URL: https://old.com → https://new.com

Commands

CommandDescription
envsync initScaffold .envsync.yml and generate or import a key
envsync checkValidate local .env files against the schema
envsync diffCompare local state to the remote
envsync pushEncrypt and push to the remote store
envsync pullPull and decrypt from the remote store
envsync key fingerprintPrint the key fingerprint for verification
envsync doctorDiagnose key, permissions, and remote issues

Global options

OptionDescription
--configPath to .envsync.yml (default: .envsync.yml)
--redactHide secret values in output
--dry-runPreview changes without writing
--forceOverwrite existing key or config

Key distribution

The encryption key lives at ~/.envify/.<project>.key on each machine. It is never committed to the repository.

Sharing the key with a new teammate

Preferred (no shell history):

# Teammate A: print the key
cat ~/.envify/.my-app.key
# Teammate B: import itprintf"%s""<hex-from-teammate-a>"| envsync init --stdin-key --project my-app

Verify you share the same key:

envsync key fingerprint
# envsync:v1:3a7c2f91b4 ← must match on both machines

CI environments

export ENVSYNC_KEYFILE=/run/secrets/envsync.key
envsync check
envsync push

Or pass a key file explicitly:

envsync init --key-file /run/secrets/envsync.key --project my-app

Schema reference

KEY_NAME:
required: truetype: string # string | int | bool | enumallowed: # only for type: enum
- development
- productiondefault: "3000"# hint shown in check output when missingscope: shared # shared (synced) | personal (local only)secret: true # redact value in diff/check output

Types

TypeValid values
stringAny string
intInteger, e.g. 3000
booltrue / false / 1 / 0 / yes / no
enumOne of the values in the allowed list

Scopes

ScopePushedPulledValidated
sharedyesyesyes
personalnonoyes, locally

Personal keys let each developer use their own ports, local service URLs, or feature flags without polluting the shared remote.


Remote types

file (MVP, default)

Stores encrypted blobs and a manifest in a local directory. Commit .envsync-remote/ to a private repository for team sharing, or place it on any shared volume.

remote:
type: filepath: .envsync-remote

Layout:

.envsync-remote/
├─ manifest.json
└─ blobs/
└─ 2025-01-15T10-30-00-000Z..env.shared.enc

Future remote types: http, s3, vault.


Security

  • Encryption: AES-256-GCM with a per-push random IV
  • Associated data: <project>:<filePath> binds ciphertext to context
  • Key storage: ~/.envify/.<project>.key at 0600 permissions
  • Secret values: redacted in diff and check output (secret: true)
  • Backups: .env files are backed up with a timestamp before every pull
  • The remote never sees plaintext — all encryption/decryption is local

What this is NOT

  • Not a replacement for production secret managers (Vault, AWS Secrets Manager)
  • Not suitable for storing production credentials without additional controls
  • Not audited — treat it as a developer-experience tool, not a security boundary

Development

# Install dependencies
npm install
# Type check
npm run typecheck
# Run all tests
npm test# Run with coverage
npm run coverage
# Lint
npm run lint
# Format
npm run format
# Build
npm run build
# Run locally without building
npm run dev -- check
npm run dev -- init --project my-app

Project structure

sdk-node/
├─ bin/envsync.ts # CLI entrypoint
├─ src/
│ ├─ index.ts # Public SDK exports
│ ├─ cli/ # Subcommand handlers
│ ├─ core/ # Business logic
│ └─ util/ # fs, log, str helpers
├─ tests/
│ ├─ unit/ # Unit tests per module
│ └─ integration/ # End-to-end flow tests
└─ fixtures/ # Sample .env and .envsync.yml files

CI integration example

- name: Check env varsrun: | export ENVSYNC_KEYFILE=/run/secrets/envsync_key npx envsync check

Exit codes

CodeMeaning
0Success
1General error
2Validation failed
3Diff found differences
4Remote not found

Roadmap

  • http remote provider
  • s3 remote provider
  • Key rotation (envsync key rotate)
  • Schema inference from existing .env (envsync init --infer)
  • Shell completions (bash, zsh, fish)
  • Multiple environment support (.env.staging, .env.production)

License

MIT — see LICENSE

About

validate, diff, and sync .env files for teams with a simple CLI, schema, and an encrypted “remote” store.

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages