Penv Cloud
Start free
Docs
Conceptsince 1.0.0-alpha.3

How penv works

penv validates every value against your committed schema file, then starts your program with those values in its environment.

penv is one binary. It validates every value against your committed .env.schema, then starts your program with those values in its environment.

Lifecycle

Declare. penv init reads your value files and writes .env.schema beside them: key names, types, and which keys are required. The schema carries a value only when it is not secret, such as 3000 or us-east-1.

Check. Every run validates the values before the program starts. The check runs inside the binary, so a Go service with no penv library still gets a refusal that names the key.

Store. penv push moves your shared values (.env, .env.<env>) to Penv Cloud and deletes those files. Your teammate then needs only penv run.

Run. penv run -- pnpm dev puts the values in the child process environment only; your shell never sees them.

The committed files

.env.schema
# @penv=acme/api-gateway

# @type=url
DATABASE_URL=

# @type=string(startsWith=sk_) @rotate=90d
STRIPE_SECRET_KEY=

# @type=url @sensitive=false
NEXT_PUBLIC_APP_URL=http://localhost:3000

# @type=port
PORT=3000

The comment lines above a key are its decorators, written in @env-spec. Schema and types covers what penv adds. Settings live in .penv/config.toml beside it; penv loads no plugins.

Value files after push

After push, we hold the shared values and penv pull writes them back to a file on demand. *.local files stay on your machine.

penv push deletes the files it moved.

Child process environment

penv run hands the child every key it resolved, plus PENV_ENV set to the environment it read. penv masks every value not marked public in the child's output on every run; under a coding agent it also seals @hosts keys (coding agents).

A key in a value file but absent from the schema is masked too, and penv check reports it as drift.

Application code

Your code keeps reading process.env.DATABASE_URL, or the language's equivalent. penv gen writes a typed file over those names in TypeScript, Python, Go, Rust, PHP, Java or C#.

Next: where a value lives.