왜 나는 nevr‑env를 만들었는가 — 그리고 process.env가 더 나은 대우를 받아야 하는 이유
I’m happy to translate the article for you, but I don’t have access to the full text of the linked page. Could you please paste the content you’d like translated (excluding any code blocks or URLs you want to keep unchanged)? Once I have the text, I’ll provide a Korean translation while preserving the original formatting and markdown.
Source: …
환경 변수의 문제점
앱이 자꾸 크래시하고, 비밀이 유출되고, .env 파일을 슬랙에 복사‑붙여넣는 일에 지쳤습니다.
모든 개발자에게는 이런 순간이 있습니다:
- 금요일에 배포합니다. CI가 통과합니다. 집에 가서 생산성을 느낍니다.
- 알림이 옵니다: “프로덕션에서 앱이 크래시하고 있어요.”
범인은? DATABASE_URL이 설정되지 않았습니다. 앱이 process.env.DATABASE_URL을 읽어 undefined를 얻고, 이를 연결 문자열로 조용히 넘겼습니다. Postgres는 이를 좋아하지 않았습니다.
이 정확한 버그를 인정하고 싶지 않을 정도로 여러 번 마주했습니다. 매번 해결 방법은 똑같았습니다: .env.example에 한 줄을 더 추가하고, 팀원들이 README를 읽길 바라며, 넘어가는 것이었습니다.
현재 도구가 실패하는 이유
- 시작 시점에 검증이 없음 –
process.env.PORT는string | undefined타입입니다.PORT를 빼먹으면 서버가undefined에서 조용히 리스닝합니다. - 타입 안전성 부족 –
process.env.ENABLE_CACHE는"true"(문자열)이며,true(불리언)가 아닙니다. 모든 개발자가 자신만의 파싱 로직을 작성합니다. - 비밀의 산재 – 팀은 슬랙 DM, 구글 문서 등으로 비밀을 공유합니다.
.env.example은 언제나 오래되었습니다. - 보일러플레이트가 곳곳에 – 새 프로젝트마다 Zod 스키마를 복사하고
DATABASE_URL: z.string().url(),PORT: z.coerce.number()등을 똑같이 작성해야 합니다.
t3‑env 격차
t3-env는 한 단계 진보한 것이었습니다: Zod를 사용한 타입‑안전한 환경 변수 검증. 저는 이를 사용했고 마음에 들었습니다.
하지만 프로젝트가 커지면서 다음과 같은 문제점들이 드러났습니다:
// Every. Single. Project.
export const env = createEnv({
server: {
DATABASE_URL: z.string().url(),
REDIS_URL: z.string().url(),
STRIPE_SECRET_KEY: z.string().startsWith("sk_"),
STRIPE_WEBHOOK_SECRET: z.string().startsWith("whsec_"),
OPENAI_API_KEY: z.string().startsWith("sk-"),
RESEND_API_KEY: z.string().startsWith("re_"),
// ... 20 more lines of the same patterns
},
});
- 저는 8개의 프로젝트에서 동일한 스키마를 반복해서 작성하고 있었습니다. Stripe가 키 형식을 변경하면 모든 프로젝트를 일일이 업데이트해야 했습니다.
- 새로운 팀원이 레포를 클론하고
npm run dev를 실행하면 검증 오류가 가득한 화면을 마주하고, 어디에 무엇을 넣어야 할지 파악하는 데 30분 정도를 소비하게 됩니다.
Source: …
nevr‑env 소개
nevr-env는 환경 수명주기 프레임워크입니다 — 단순히 검증을 넘어 설정부터 프로덕션 모니터링까지 전체 수명주기를 관리합니다.
간소화된 설정
import { createEnv } from "nevr-env";
import { postgres } from "nevr-env/plugins/postgres";
import { stripe } from "nevr-env/plugins/stripe";
import { openai } from "nevr-env/plugins/openai";
import { z } from "zod";
export const env = createEnv({
server: {
NODE_ENV: z.enum(["development", "production", "test"]),
API_SECRET: z.string().min(10),
},
plugins: [
postgres(),
stripe(),
openai(),
],
});
세 개의 플러그인이 15줄 이상의 수동 스키마를 대체합니다. 각 플러그인은 올바른 형식을 알고, 적절한 검증을 제공하며, 자동 탐지(예: 실행 중인 Postgres 컨테이너를 자동으로 감지)까지 포함합니다.
인터랙티브 온보딩
새 개발자가 누락된 변수를 가지고 앱을 실행하면:
$ npx nevr-env fix
오류 메시지 대신 인터랙티브 마법사가 나타납니다:
? DATABASE_URL is missing
This is: PostgreSQL connection URL
Format: postgresql://user:pass@host:port/db
> Paste your value: █
온보딩 시간이 “Slack에 물어보기”에서 “명령 하나 실행”으로 단축됩니다.
암호화된 비밀 관리 (Vault)
# 팀당 한 번 키 생성
npx nevr-env vault keygen
# .env를 vault 파일로 암호화
npx nevr-env vault push # .nevr-env.vault 생성 (커밋해도 안전)
# 새 팀원이 레포를 받아 복호화
npx nevr-env vault pull # 로컬에 .env 생성
- Vault는 AES‑256‑GCM 암호화와 PBKDF2 (600 K iterations) 를 사용합니다.
- 암호화 키는 레포지토리에 절대 저장되지 않습니다.
- 작은 팀을 위한 Slack DM이나 유료 비밀 관리 SaaS가 필요 없습니다.
비밀 스캔
$ npx nevr-env scan
Found 2 secrets in codebase:
CRITICAL src/config.ts:14 AWS Access Key (AKIA...)
HIGH lib/api.ts:8 Stripe Secret Key (sk_live_...)
CI에서 실행되어 비밀이 git 히스토리에 들어가기 전에 잡아냅니다 — 별도의 도구가 필요 없습니다.
플러그인
| 카테고리 | 플러그인 |
|---|---|
| 데이터베이스 | postgres(), redis(), supabase() |
| 인증 | clerk(), auth0(), better-auth(), nextauth() |
| 결제 | stripe() |
| AI | openai() |
| 이메일 | resend() |
| 클라우드 | aws() |
| 프리셋 | vercel(), railway(), netlify() |
커스텀 플러그인 만들기
import { createPlugin } from "nevr-env";
import { z } from "zod";
export const myService = createPlugin({
name: "my-service",
schema: {
MY_API_KEY: z.string().min(1),
MY_API_URL: z.string().url(),
},
});
CLI 명령
| 명령 | 설명 |
|---|---|
init | 프로젝트에 nevr-env 설정 |
check | 모든 env 변수 검증 (CI 친화적) |
fix | 누락된 변수에 대한 인터랙티브 마법사 |
generate | 스키마에서 .env.example 자동 생성 |
types | env.d.ts 타입 정의 생성 |
scan | 코드에서 유출된 비밀 찾기 |
diff | 버전 간 스키마 비교 |
rotate | 비밀 회전 상태 추적 |
ci | CI 설정 생성 (GitHub Actions, Vercel, Railway) |
dev | 검증 후 개발 서버 실행 |
watch | .env 변경 시 실시간 검증 재로드 |
vault | 암호화된 비밀 관리 (keygen/push/pull/status) |
설치
pnpm add nevr-env zod
npx nevr-env init
init 마법사는 프레임워크를 감지하고, 실행 중인 서비스를 찾아, 완전한 구성을 생성합니다.
Links
- GitHub: https://github.com/nevr-ts/nevr-env
- npm: https://www.npmjs.com/package/nevr-env
- Docs: https://nevr-ts.github.io/nevr-env/
만약 env 변수가 없어 생산 시간이 손실된 적이 있다면, 여러분의 이야기를 듣고 싶습니다. 그리고 nevr-env가 이를 해결해 주었다면, GitHub에 별표를 달아 주시면 큰 힘이 됩니다.
Yalelet Dessalegn이 nevr‑ts 생태계의 일환으로 제작했습니다.