Penv Cloud
Start free
Docs
Guidesince 1.0.0-alpha.3

From a .env file

What penv init reads from your .env, what it infers for each key, and which values it keeps out of .env.schema.

penv init

penv init reads .env and your other value files in the working directory (.env wins a duplicate key) and writes .env.schema beside them. Nothing leaves your machine, and .env stays in place.

If .env.schema exists, init keeps it, still updates .gitignore and .penv/config.toml, and points you to penv check. penv init --force writes the schema again.

Inference per key

PropertyRule
TypeFrom the shape of the value, written as @type=.
RequiredAn empty value is required. A value on the line becomes the default and makes the key optional.
SensitiveSensitive unless its value is copied as a default, or the key has a bundler prefix: NEXT_PUBLIC_, VITE_, PUBLIC_, EXPO_PUBLIC_, NUXT_PUBLIC_, REACT_APP_, GATSBY_, VUE_APP_, STORYBOOK_.
.env.schema
# @type=url
DATABASE_URL=

# @type=string
STRIPE_SECRET_KEY=

# @type=port @sensitive=false
PORT=3000

# @type=boolean @sensitive=false
DEBUG=true

Values kept out of the schema

A value is copied as a default only when the key has a bundler prefix, or the value is one of:

  • a boolean or an integer
  • a lowercase word of letters
  • a short lowercase slug such as us-east-1, gpt-4o or api.internal
  • a localhost URL with no user information and no query string

A key whose name contains one of these words, or its plural, never has its value copied, whatever the value or prefix:

AUTH KEY SECRET TOKEN PASSWORD PASSWD PASSPHRASE PASS PWD PW CREDENTIAL CRED DSN SALT SEED SIGNATURE

NEXT_PUBLIC_SUPABASE_ANON_KEY therefore keeps its value out of the schema and is still marked public, because the prefix puts it in the browser bundle.

Edit the schema

.env.schema
# The gateway the API talks to.
# @type=string(startsWith=sk_) @rotate=90d
STRIPE_SECRET_KEY=

# @type=enum(development,staging,production)
NODE_ENV=development

Your decorators follow @env-spec (item decorators, data types). penv's additions such as @rotate, and its deviations: the .env.schema format.

penv check reports, among others:

DiagnosticSeverityCause
unknown_decoratorWarning; penv ignores the decoratorA decorator penv does not act on.
sensitive_public_keyErrorA bundler-prefixed key marked @sensitive.

Unwritable lines

penv writes only the dotenv subset that Node's util.parseEnv and dotenv both read back (the .env.schema format). Its reader accepts more of your file and warns once per value with line and column, never the character. init counts those lines; penv check names them.

Undo

ModeState after initUndo
Local.env.schema and .penv/config.toml written; .env, .env.*, !.env.schema added to .gitignore; .env untouchedDelete .env.schema, the .gitignore lines, and .penv/config.toml if init created it
Cloud.env and .env.<env> deleted by penv pushpenv pull writes .env again

Set up the workspace in the console