惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
F
Fortinet All Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
爱范儿
爱范儿
美团技术团队
H
Hackread – Cybersecurity News, Data Breaches, AI and More
有赞技术团队
有赞技术团队
博客园_首页
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
V
Visual Studio Blog
Jina AI
Jina AI
博客园 - Franky
量子位
MongoDB | Blog
MongoDB | Blog
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
U
Unit 42
aimingoo的专栏
aimingoo的专栏
M
MIT News - Artificial intelligence

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
10 Things Nobody Tells You About process.env
Odejobi Abiola Samuel · 2026-06-23 · via DEV Community

10 Things Nobody Tells You About process.env

I've burned myself on most of these so you don't have to. Here's what I wish someone had told me early on.

1. Keys are case-sensitive on Linux, case-insensitive on Windows

process.env.PORT = "3000"
console.log(process.env.port) // undefined on Linux, "3000" on Windows

This one got me during a "works on my machine" incident. My Windows dev box ran fine. The Linux CI server crashed because a teammate typed env.port instead of env.PORT. Your CI runs Linux. Your dev box probably runs macOS or Windows. Case-sensitivity differences will bite you.

How to handle it: Use a validation layer that throws on missing keys. A simple getEnv("PORT") will catch typos at startup.

2. Values are always strings

console.log(typeof process.env.PORT) // "string" even if you set PORT=3000

Number(process.env.PORT) can return NaN without throwing. Boolean values like "false" are truthy strings.

How to handle it: Always parse. If you use a schema library like CtroEnv, it coerces types and throws on invalid input.

3. process.env is NOT the same as .env

This confused me for way too long. process.env is whatever the shell gave the process. A .env file is just a text file dotenv reads to populate process.env. Node doesn't touch .env files on its own.

// This won't read .env automatically
console.log(process.env.MY_VAR) // undefined

How to handle it: Call dotenv.config() at entry, or use @ctroenv/node which loads .env files automatically.

4. You can set env vars per-command

PORT=4000 node app.js

This sets PORT only for that single process. It doesn't pollute your shell session. Super useful for one-off runs or testing different configurations without editing files.

console.log(process.env.PORT) // "4000"

5. process.env is mutable at runtime

process.env.DATABASE_URL = "postgres://hacker:gotme@evil.com/db"

I've seen code that modifies process.env to "fix" config at runtime. Don't do this. If something is wrong, fail fast and fix the source. Mutating process.env makes debugging a nightmare — you can't trust what you see anymore.

If you're using CtroEnv, the returned object is frozen. You literally can't mutate it.

6. Next.js inlines NEXT_PUBLIC_ vars at build time

// This gets replaced at BUILD time, not runtime
console.log(process.env.NEXT_PUBLIC_API_URL)

Next.js replaces process.env.NEXT_PUBLIC_* references with their actual values during next build. After that, changing the env var on the server does nothing. You have to rebuild.

What this means: If you change NEXT_PUBLIC_API_URL on your production server, your app still uses the old value. Found this out the hard way during a hotfix.

7. process.env is not available in the browser

Browsers don't have process. If you're using Webpack or Vite, they emulate process.env at build time for variables you specifically expose.

// In the browser with Vite:
console.log(import.meta.env.VITE_API_URL) // works
console.log(process.env.PORT)             // ReferenceError

How to handle it: Use Vite's import.meta.env with the VITE_ prefix, or reach for a framework adapter that handles this split automatically.

8. NODE_ENV is not set by default

I used to assume NODE_ENV was always there. It's not. Node.js doesn't set it. Your framework probably does — Express sets it to "development" by default, Next.js sets it during build — but if you're writing a bare Node script, you need to set it yourself.

if (process.env.NODE_ENV === "production") {
  // This might never run if you forgot to set it
}

How to handle it: Always provide a default. Or validate it exists if your app can't run without it.

9. Env var values are limited to ~32KB on some systems

This one's rare but brutal when it hits. Some Unix systems cap a single environment variable value at 32KB (or even smaller on older kernels). Windows has a 32,767 character limit per variable. If you're stuffing a PEM-encoded certificate or a large JSON blob into an env var, you might hit invisible truncation.

How to handle it: Use files for large config values. Read them from disk instead of env vars.

10. Env vars are inherited by child processes

const child = spawn("node", ["worker.js"])
// child inherits ALL of parent's env vars

This means every child process gets your secrets, your database credentials, your API keys — even if the child doesn't need them. If the child is a third-party CLI tool or something you don't fully control, those secrets are now in its memory space.

How to handle it: Be explicit. Pass only what's needed:

spawn("node", ["worker.js"], {
  env: { ONLY_WHAT_THEY_NEED: "value" }
})

Or use CtroEnv's secret masking to at least prevent accidental logging of sensitive values.


Links: GitHub | Docs