# Env Drift

> Find environment-variable drift between code, .env files, .env.example, and platform config (vercel.json / netlify.toml). Use whenever a deploy fails with undefined env vars, the user mentions 'missing environment variable', 'works locally but env is undefined in prod', sets up a new deploy environment, onboards a teammate, or before any first deploy of a project. Runs fully offline — no API keys, no network, no credentials.

- Skill: `starr-del/env-drift` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add starr-del/env-drift`
- Raw SKILL.md: https://api.skillmd.com/api/skills/starr-del/env-drift/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: Starr-del (https://skillmd.com/u/starr-del)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/starr-del/env-drift

---


# env-drift

Part of **shipsafe** — offline deploy-safety skills. Every script is stdlib-only Python 3.8+; nothing leaves the machine.

```bash
python3 scripts/env_drift.py <project_root> [--json]
```

Reports four classes:
- **MISSING** — read in code, documented nowhere; a fresh deploy WILL fail on these. Highest priority.
- **UNDOCUMENTED** — in local .env but not .env.example; the deploy platform and teammates can't reproduce the environment.
- **UNUSED** — declared but never read; dead config or a typo'd name (a typo shows up as one UNUSED + one MISSING pair — point this out when you see it).
- **CLIENT_LEAK** — secret-named vars with NEXT_PUBLIC_/VITE_/etc. prefixes. These are bundled into public JavaScript. Treat as critical; the secret must be rotated and moved server-side.
- **HARDCODED_URL** — `http://localhost:*` baked into code (test files exempt). Works in dev, dead in production; the fix is an env var or relative path.
- **SERVER_ENV_IN_CLIENT** — non-public `process.env.X` read inside a `'use client'` component. In the browser it's `undefined` (silent breakage), and renaming it to NEXT_PUBLIC_* is only acceptable when it is genuinely not a secret.

Detects references in JS/TS (process.env, import.meta.env), Python (os.environ, os.getenv), and Deno. Runtime-provided vars (NODE_ENV, VERCEL_URL...) are excluded automatically.

After running: fix MISSING by adding the vars to the platform dashboard AND .env.example, and remind the user that platform env changes require a redeploy to take effect.

Exit codes: 0 clean, 1 findings.

All paths below are relative to this skill's directory (env-drift/).

