Team Collaboration with evnx sync
Real-world patterns for using evnx sync with multiple developers, onboarding, and merge workflows.
Prerequisites
Team Collaboration with evnx sync
Who this is for
This guide is for teams of 2+ developers using evnx to manage environment variables. You'll learn patterns for onboarding, daily workflows, and avoiding merge conflicts.
Before you start
The team sync workflow
Key principles
- ›
.env.exampleis the source of truth for variable names - ›
.envis personal — never commit, always gitignored - ›Sync forward = share new variables with team
- ›Sync reverse = get team's new variables locally
Scenario 1: Adding a new variable
Context: Alice needs STRIPE_WEBHOOK_SECRET for a new feature.
Step 1: Alice adds to her .env
echo "STRIPE_WEBHOOK_SECRET=whsec_abc123" >> .envStep 2: Alice updates the team template
evnx sync --direction forward --dry-run
📋 Preview:
Target: .env.example (action: Add)
🔒 STRIPE_WEBHOOK_SECRET = YOUR_KEY_HERE
# Apply the change
evnx sync --direction forward
✓ Updated .env.example (+1 variables)Step 3: Commit and push
git add .env.example
git commit -m "feat: add STRIPE_WEBHOOK_SECRET to template"
git pushResult for teammates:
# .env.example now has:
STRIPE_WEBHOOK_SECRET=YOUR_KEY_HEREDon't commit secrets
Alice's real value whsec_abc123 stays in her .env only. The template gets the safe placeholder YOUR_KEY_HERE.
Scenario 2: Onboarding a new developer
Context: Bob joins the team and clones the repo.
Step 1: Bob clones and enters project
git clone git@github.com:team/project.git
cd projectStep 2: Bob checks what's needed
ls -la
# Sees: .env.example (committed), .env (missing, gitignored)Step 3: Bob creates his local .env
evnx sync --direction reverse
ℹ️ .env not found, creating from .env.example
✓ Created .env
⚠️ Replace placeholder values with real credentials!Step 4: Bob edits with real values from team password manager
nano .env
# Changes:
# DATABASE_URL=postgresql://user:password@localhost:5432/dbname
# To:
# DATABASE_URL=postgresql://bob:realpass@prod-db:5432/appStep 5: Bob secures permissions
chmod 600 .envStep 6: Bob validates setup
evnx validate
✓ All variables present and valid✅ Bob is ready to code!
Document the onboarding flow
Add this to your README:
Setup
- ›Clone repo
- ›Run
evnx sync --direction reverseto create .env - ›Edit .env with credentials from [password manager]
- ›Run
chmod 600 .envandevnx validate
Scenario 3: Handling merge conflicts in .env.example
Context: Alice and Bob both add different variables and push around the same time.
Step 1: Alice pushes first
git push
# ✓ SuccessStep 2: Bob tries to push
git push
# ✗ rejected: remote contains work you don't haveStep 3: Bob pulls and sees conflict
git pull
# CONFLICT (content): Merge conflict in .env.exampleStep 4: Bob opens .env.example to resolve
nano .env.example
# Keeps both new variables, removes conflict markersStep 5: Bob validates the resolved file
evnx validate
✓ All variables presentStep 6: Bob completes the merge
git add .env.example
git commit -m "Resolve merge conflict in .env.example"
git pushWhy this works
Because .env.example only contains variable names and placeholders (no secrets), merge conflicts are safe to resolve manually.
Scenario 4: Syncing before a pull request
Best practice: Always sync forward before opening a PR that adds new environment variables.
Before creating PR:
evnx sync --direction forward --dry-runIf preview shows new variables:
# 1. Apply the sync
evnx sync --direction forward
# 2. Commit the template change
git add .env.example
git commit -m "chore: sync .env.example with new variables"
# 3. Now create your PR
gh pr create --title "feat: add new feature"In your PR description:
### Environment Changes
- Added `NEW_API_KEY` to `.env.example` (placeholder: `YOUR_KEY_HERE`)
- No secrets committed — all values are safe placeholders
### Testing
# Preview the sync change:
$ evnx sync --direction forward --dry-run
📋 Preview:
🔒 NEW_API_KEY = YOUR_KEY_HERECommunication best practices
When to notify the team
| Change | Notify team? | How |
|---|---|---|
| New required variable | Yes | Slack/PR description |
| Removed variable | Yes | Deprecation notice in PR |
| Changed placeholder pattern | Maybe | Update .evnx/placeholders.json + docs |
| Security-related variable | Yes | Direct message + PR |
Template for team notifications
**Environment Update** 🔄
A new environment variable has been added:
- **Name:** `NEW_SERVICE_URL`
- **Purpose:** URL for the new analytics service
- **Placeholder:** `https://api.demo.example.com`
- **Required:** Yes (app won't start without it)
**Action needed:**
1. Pull latest changes: `git pull`
2. Sync to your .env: `evnx sync --direction reverse`
3. Edit .env with the real URL from [password manager]
4. Validate: `evnx validate`
Questions? Reply here or ping @env-team.Avoiding common team pitfalls
"It works on my machine"
Problem: Developer has a variable locally that's not in .env.example.
Prevention:
# Add to pre-commit hook or CI:
evnx sync --direction forward --dry-run --force
if ! git diff --quiet .env.example; then
echo "⚠️ .env.example needs updates!"
echo "Run: evnx sync --direction forward"
exit 1
fiSecrets in .env.example
Problem: Someone accidentally commits real values.
Prevention:
- ›Use
--dry-runbefore every sync forward - ›Add CI check:
grep -E "(sk_live|password)" .env.example && exit 1 - ›Use custom placeholders that look fake:
sk_demo_XXXXXXXX
Merge conflicts in .env
Problem: .env should never be in Git, but someone commits it.
Prevention:
- ›Ensure
.envis in.gitignorefrom day one - ›Add pre-commit hook to block
.envcommits - ›Educate team: "If you see
.envingit status, don't add it!"
Advanced: Custom placeholders for teams
Create .evnx/placeholders.json for consistent team patterns:
{
"patterns": {
".*_API_KEY$": "sk_demo_XXXXXXXXXXXXXXXX",
".*_SECRET$": "demo_secret_placeholder",
"DATABASE_URL": "postgresql://demo:demo@localhost:5432/demo_db"
},
"default": "REPLACE_IN_PRODUCTION"
}Team workflow:
- ›Commit
.evnx/placeholders.jsonto repo - ›Document in README: "We use custom placeholders — see
.evnx/" - ›Use in sync:
evnx sync --template-config .evnx/placeholders.json
Share the config
Commit .evnx/placeholders.json so every teammate gets the same placeholder patterns automatically.
Checklist: Team sync health
Run this monthly or when onboarding:
# 1. Verify .env.example is up to date
evnx sync --direction forward --dry-run --force
# 2. Check for secrets in template
grep -iE "(sk_live|password|secret)" .env.example | grep -v "YOUR_\|placeholder\|demo" && echo "⚠️ Potential secrets found!"
# 3. Validate naming conventions
evnx sync --naming-policy error --dry-run
# 4. Confirm .gitignore is correct
git check-ignore .env # Should output: .env
# 5. Test onboarding flow (in fresh directory)
mkdir /tmp/test-onboarding && cd /tmp/test-onboarding
git clone <repo> .
evnx sync --direction reverse # Should work without errorsRelated guides
- ›CI/CD Integration — Automate these checks
- ›Security Best Practices — Protect team secrets
- ›Configuration Reference — Advanced placeholder patterns
Team sync mastery
With these patterns, your team will never lose track of environment variables again. Sync early, sync often, and always preview with --dry-run.